尽管PostgreSQL中的索引不需要维护或调优,但检查真实查询工作负载到底实际使用了哪些索引,仍然很重要。检查某个单独查询的索引使用情况,可以使用EXPLAIN命令;它在这方面的应用见Section 14.1。也可以像Section 27.2中描述的那样,在运行中的服务器上收集索引使用的总体统计信息。
很难给出一个确定应该创建哪些索引的通用流程。前面各节的示例已经展示了若干典型情形。通常需要做大量实验。下面这部分会给出一些相关提示:
一定要先运行ANALYZE。这个命令会收集表中值分布的统计信息。估计查询会返回多少行,需要这些信息;而规划器要为每种可能的查询计划分配现实的代价,也需要这些信息。如果没有真实统计信息,系统就会假定一些默认值,而这些默认值几乎肯定并不准确。因此,在没有运行ANALYZE的情况下去检查应用的索引使用情况,基本上是徒劳的。更多信息见Section 24.1.3和Section 24.1.6。
用真实数据做实验。使用测试数据来设置索引,只会告诉你测试数据需要什么索引,仅此而已。
特别要避免使用非常小的测试数据集。虽然在 100000 行里选 1000 行可能适合用索引,但在 100 行里选 1 行几乎不适合,因为这 100 行大概都能放进一个磁盘页,而没有任何计划能比顺序取一个磁盘页更快。
另外,在编造测试数据时也要小心;如果应用尚未投入生产,这往往无法避免。非常相似、完全随机、或者按排序顺序插入的值,都会让统计信息偏离真实数据应有的分布。
当索引没有被使用时,强制使用它们对测试会很有帮助。有一些运行时参数可以关闭不同的计划类型(见Section 19.7.1)。例如,关闭顺序扫描(enable_seqscan)和嵌套循环连接(enable_nestloop)这两种最基本的计划,就会迫使系统使用不同的计划。如果系统仍然选择顺序扫描或嵌套循环连接,那么索引未被使用很可能有更根本的原因,例如查询条件并不匹配该索引。(前面各节已经解释了什么样的查询可以使用什么样的索引。)
如果强制使用索引后确实使用了索引,那么就有两种可能:要么系统是对的,使用索引确实不合适;要么查询计划的代价估计并未反映现实。因此,你应该分别在有索引和无索引的情况下对查询计时。EXPLAIN ANALYZE命令在这里会很有帮助。
如果发现代价估计是错的,那么又有两种可能。总成本是根据每个计划节点的逐行成本乘以该计划节点的选择率估计计算出来的。计划节点的估计成本可以通过运行时参数来调整(见Section 19.7.2)。而选择率估计不准确,则是因为统计信息不足。可以尝试通过调整统计信息收集参数来改进这一点(见ALTER TABLE)。
如果你无法把这些成本调得更合适,那么可能就不得不退而求其次,显式强制使用索引。你也可能希望联系PostgreSQL开发者来研究这个问题。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。