mfvanek/pg-index-health-sql

GitHub: mfvanek/pg-index-health-sql

一套纯 SQL 编写的 PostgreSQL 数据库 Schema 健康检查查询集,用于检测索引、表结构、外键和数据类型等方面的潜在问题并推动最佳实践落地。

Stars: 114 | Forks: 18

# pg-index-health-sql **pg-index-health-sql** 是一个用于分析 PostgreSQL 模式、检测问题并推广最佳实践的 SQL 查询集合。 [![Lint Code Base](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/8bfb2199dd055440.svg)](https://github.com/mfvanek/pg-index-health-sql/actions/workflows/linter.yml) [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/mfvanek/pg-index-health-sql/blob/master/LICENSE "Apache License 2.0") ## 这是什么? **pg-index-health-sql** 提供了一组经过精心设计的原始 SQL 查询,旨在识别 PostgreSQL 数据库中常见的模式问题——例如冗余索引、缺少主键或低效的表结构。 它支持轻量级、数据库原生的分析,无需外部库或框架,适合直接在 psql 会话、脚本或监控仪表板中使用。 ## 支持的 PostgreSQL 版本 [![PostgreSQL 14](https://img.shields.io/badge/PostgreSQL-14-green.svg)](https://www.postgresql.org/about/news/postgresql-14-released-2318/ "PostgreSQL 14") [![PostgreSQL 15](https://img.shields.io/badge/PostgreSQL-15-green.svg)](https://www.postgresql.org/about/news/postgresql-15-released-2526/ "PostgreSQL 15") [![PostgreSQL 16](https://img.shields.io/badge/PostgreSQL-16-green.svg)](https://www.postgresql.org/about/news/postgresql-16-released-2715/ "PostgreSQL 16") [![PostgreSQL 17](https://img.shields.io/badge/PostgreSQL-17-green.svg)](https://www.postgresql.org/about/news/postgresql-17-released-2936/ "PostgreSQL 17") [![PostgreSQL 18](https://img.shields.io/badge/PostgreSQL-18-green.svg)](https://www.postgresql.org/about/news/postgresql-18-released-3142/ "PostgreSQL 18") ### 支持先前版本的 PostgreSQL 不再保证与先前 PostgreSQL 版本的兼容性,但极有可能是兼容的。 我们仅关注当前处于维护期的 PostgreSQL 版本。 欲了解更多信息,请参阅 [PostgreSQL 版本控制策略](https://www.postgresql.org/support/versioning/)。 ## 可用的检查项 **pg-index-health-sql** 允许您检测以下问题: 1. 无效(损坏)的索引 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/invalid_indexes.sql))。 2. 重复(完全相同)的索引 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/duplicated_indexes.sql))。 3. 交叉(部分相同)的索引 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/intersected_indexes.sql))。 4. 未使用的索引 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/unused_indexes.sql))。 5. 没有关联索引的外键 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/foreign_keys_without_index.sql))。 6. 包含空值的索引 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/indexes_with_null_values.sql))。 7. 缺少索引的表 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/tables_with_missing_indexes.sql))。 8. 没有主键的表 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/tables_without_primary_key.sql))。 9. 索引[膨胀](https://www.percona.com/blog/2018/08/06/basic-understanding-bloat-vacuum-postgresql-mvcc/) ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/bloated_indexes.sql))。 10. 表[膨胀](https://www.percona.com/blog/2018/08/06/basic-understanding-bloat-vacuum-postgresql-mvcc/) ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/bloated_tables.sql))。 11. 没有[描述](https://www.postgresql.org/docs/current/sql-comment.html)的表 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/tables_without_description.sql))。 12. 没有[描述](https://www.postgresql.org/docs/current/sql-comment.html)的列 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/columns_without_description.sql))。 13. [json](https://www.postgresql.org/docs/current/datatype-json.html) 类型的列 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/columns_with_json_type.sql))。 14. 不是主键的 [serial 类型](https://www.postgresql.org/docs/current/datatype-numeric.html#DATATYPE-SERIAL) 列 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/columns_with_serial_types.sql))。 15. 没有[描述](https://www.postgresql.org/docs/current/sql-comment.html)的函数 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/functions_without_description.sql))。 16. [包含布尔值](https://habr.com/ru/companies/tensor/articles/488104/)的索引 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/indexes_with_boolean.sql))。 17. 包含[无效约束](https://habr.com/ru/articles/800121/)的表 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/not_valid_constraints.sql))。 18. [数组列上](https://habr.com/ru/articles/800121/)的 B-tree 索引 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/btree_indexes_on_array_columns.sql))。 19. [序列溢出](https://habr.com/ru/articles/800121/) ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/sequence_overflow.sql))。 20. 使用 [serial 类型](https://wiki.postgresql.org/wiki/Don't_Do_This#Don.27t_use_serial)的主键 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/primary_keys_with_serial_types.sql))。 21. 重复(完全相同)的外键 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/duplicated_foreign_keys.sql))。 22. 交叉(部分相同)的外键 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/intersected_foreign_keys.sql))。 23. 名称可能溢出的对象 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/possible_object_name_overflow.sql))。 24. 未与其他表关联的表 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/tables_not_linked_to_others.sql))。 25. [列类型不匹配的](https://habr.com/ru/articles/803841/)外键 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/foreign_keys_with_unmatched_column_type.sql))。 26. 具有零个或一个列的表 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/tables_with_zero_or_one_column.sql))。 27. 名称不符合命名约定的对象 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/objects_not_following_naming_convention.sql))。 28. 名称不符合命名约定的列 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/columns_not_following_naming_convention.sql))。 29. 使用 varchar 列而不是 uuids 的主键 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/primary_keys_with_varchar.sql))。 30. [varchar(n)](https://www.postgresql.org/docs/current/datatype-character.html) 类型的列 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/columns_with_fixed_length_varchar.sql))。 31. 在非空列上带有不必要 where 子句的索引 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/indexes_with_unnecessary_where_clause.sql))。 32. 极有可能是自然键的主键 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/primary_keys_that_most_likely_natural_keys.sql))。 33. [money](https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_money) 类型的列 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/columns_with_money_type.sql))。 34. [时间戳在中间的](https://habr.com/ru/companies/tensor/articles/488104/)索引 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/indexes_with_timestamp_in_the_middle.sql))。 35. [timestamp](https://wiki.postgresql.org/wiki/Don't_Do_This#Don.27t_use_timestamp_.28without_time_zone.29) 类型的列 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/columns_with_timestamp_or_timetz_type.sql))。 36. 主键列不是第一列的表 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/tables_where_primary_key_columns_not_first.sql))。 37. 除主键外所有列均可为空的表 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/tables_where_all_columns_nullable_except_pk.sql))。 38. [char(n) 类型](https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don't_use_char(n) 的列 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/columns_with_char_type.sql))。 39. 带有[继承](https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_table_inheritance)的表 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/tables_with_inheritance.sql))。 40. 多列外键中至少有一个引用列可为空 ([sql](https://github.com/mfvanek/pg-index-health-sql/blob/master/sql/foreign_keys_with_null_values.sql))。 ## 本地开发 ### Linting #### macOS/Linux 要在本地运行 super-linter: ``` docker run \ -e RUN_LOCAL=true \ -e USE_FIND_ALGORITHM=true \ -e VALIDATE_SQLFLUFF=true \ -v $(pwd):/tmp/lint \ ghcr.io/super-linter/super-linter:slim-v8.6.0 ``` #### Windows 在 Windows 上使用 `cmd`: ``` docker run ^ -e RUN_LOCAL=true ^ -e USE_FIND_ALGORITHM=true ^ -e VALIDATE_SQLFLUFF=true ^ -v "%cd%":/tmp/lint ^ ghcr.io/super-linter/super-linter:slim-v8.6.0 ``` 参见 https://github.com/super-linter/super-linter/blob/main/dependencies/python/sqlfluff.txt ``` docker run --rm ^ -v "%cd%\.github\linters\.sqlfluff":/sql/.sqlfluff:ro ^ -v "%cd%":/sql ^ -e SQLFLUFF_CONFIG=/sql/.sqlfluff ^ sqlfluff/sqlfluff:4.1.0 lint /sql ```
标签:PostgreSQL, psql, Schema分析, SQL, 主键检测, 健康检查, 冗余索引, 多线程, 开源, 性能优化, 数据库监控, 数据库索引, 数据库维护, 数据库质量, 最佳实践, 检测绕过, 模式分析, 测试用例, 系统审计, 表结构分析, 诊断工具, 请求拦截