2024 年 9 月 26 日: PostgreSQL 17 发布!
支持版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不受支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2

11.12. 检查索引使用情况 #

尽管 PostgreSQL 中的索引不需要维护或调整,但检查哪些索引实际上被实际查询工作负载使用仍然很重要。检查单个查询的索引使用情况是使用 EXPLAIN 命令完成的;它在此目的上的应用在 第 14.1 节 中进行了说明。还可以收集关于运行服务器中索引使用情况的总体统计信息,如 第 27.2 节 所述。

很难制定一个通用程序来确定要创建哪些索引。在前面的各节的示例中已经展示了一些典型的情况。通常需要大量的实验。本节的其余部分给出了一些提示。

  • 首先始终运行 ANALYZE。此命令收集有关表中值分布的统计信息。此信息需要估计查询返回的行数,这需要规划器为每个可能的查询计划分配现实的成本。在没有实际统计信息的情况下,会假定一些默认值,这些默认值几乎肯定会不准确。因此,在没有运行 ANALYZE 的情况下检查应用程序的索引使用情况是徒劳的。有关更多信息,请参见 第 24.1.3 节第 24.1.6 节

  • 使用真实数据进行实验。使用测试数据设置索引只会告诉你测试数据需要哪些索引,仅此而已。

    使用非常小的测试数据集尤其致命。从 100000 行中选择 1000 行可能是索引的候选者,但从 100 行中选择 1 行不太可能,因为 100 行可能适合单个磁盘页,并且没有计划可以击败顺序获取 1 个磁盘页。

    在编造测试数据时也要小心,当应用程序尚未投入生产时,这往往是不可避免的。非常相似、完全随机或按排序顺序插入的值会导致统计信息偏离真实数据将具有的分布。

  • 当索引未被使用时,强制使用索引以进行测试可能很有用。有一些运行时参数可以关闭各种计划类型(参见 第 19.7.1 节)。例如,关闭顺序扫描 (enable_seqscan) 和嵌套循环连接 (enable_nestloop)(这些是最基本的计划)将强制系统使用不同的计划。如果系统仍然选择顺序扫描或嵌套循环连接,那么可能存在一个更基本的原因导致索引未被使用;例如,查询条件与索引不匹配。(前面的各节解释了哪种查询可以使用哪种索引。)

  • 如果强制使用索引确实使用了索引,则有两种可能性:要么系统是正确的,并且使用索引确实不合适,要么查询计划的成本估算没有反映现实情况。因此,你应该在使用和不使用索引的情况下计时查询。这里 EXPLAIN ANALYZE 命令可能会有用。

  • 如果事实证明成本估算是错误的,那么再次有两种可能性。总成本由每个计划节点的每行成本乘以计划节点的选择性估算得出。每个计划节点的成本估算可以通过运行时参数进行调整(在 第 19.7.2 节 中描述)。不准确的选择性估算是由于统计信息不足。可以通过调整统计信息收集参数来改善这一点(参见 ALTER TABLE)。

    如果你没有成功地调整成本使其更合适,那么你可能需要诉诸于显式地强制使用索引。你可能还想联系 PostgreSQL 开发人员来检查问题。

提交更正

如果你在文档中看到任何不正确的内容、与你对特定功能的体验不符或需要进一步说明,请使用 此表格 报告文档问题。