尽管 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 开发人员以检查问题。