索引顾问(Index Advisor)可以帮助您确定应该对哪些列编制索引,以提高指定工作负载中的性能。索引顾问仅识别二叉树类型索引(单列或复合),不识别可提高性能的其他索引类型,例如GIN、GiST、Hash等。
索引顾问简介
索引顾问会尝试对INSERT、UPDATE、DELETE和SELECT语句提出索引编制建议。当调用索引顾问时,您将以一个EXPLAIN语句形式的形式提供工作负载。索引顾问为提供的查询显示查询计划和估计执行开销,但不实际执行查询。
在分析期间,索引顾问会对使用假设索引和不使用假设索引的查询执行开销进行比较。如果使用假设索引的执行开销低于不使用假设索引的执行开销,则将在EXPLAIN语句输出中报告这两个计划,计算量化改进的指标,并且索引顾问会生成创建索引所需的CREATE INDEX语句。
如果未找到降低执行开销的假设索引,则索引顾问会只显示EXPLAIN语句的原始查询计划输出,并不会实际在表上创建索引。您可以使用由索引顾问提供的CREATE INDEX语句向表添加任何建议的索引。
执行CREATE EXTENSION index_advisor会创建index_advisor_log表、show_index_recommendations()函数和index_recommendations视图,索引顾问在该表中存储分析生成的索引编制建议,使用提供的函数和视图,可以简化对结果的检索和解释。
注意事项
- 索引顾问不考虑Index-Only Scan扫描,它在提出建议时考虑索引扫描。
- 索引顾问会忽略WHERE子句中找到的任何计算。建议中的索引字段不会是任何类型的表达式,该字段将是一个简单的列名。
- 建议假设索引时,索引顾问不考虑继承。如果查询引用父表,索引顾问不对子表提出任何索引建议。
- 在恢复pg_dump备份文件(包括index_advisor_log表或对其提出索引编制建议并将这些建议存储在index_advisor_log表中的任何表)期间,可能会因对象标识符(OID)中的更改导致index_advisor_log表与恢复的表(由index_advisor_log表中的行引用)之间断开链接。
- 如果有必要在备份之前显示所提出的建议,您可以使用SQL UPDATE语句将index_advisor_log表中reloid列的旧OID替换为被引用表的新OID:
UPDATE index_advisor_log SET reloid = new_oid WHERE reloid = old_oid;
索引顾问组件
组件 | 说明 |
---|---|
index_advisor_log | 索引顾问会将索引编制建议记录在Index_advisor_log表中。 |
show_index_recommendations() | show_index_recommendations()一个PL/pgSQL函数,它解释并显示特定的索引顾问会话(由其后端进程ID标识)期间提出的建议。 |
index_recommendations | 索引顾问根据查询分析期间存储在index_advisor_log表中的信息,创建index_recommendations视图。该视图所生成输出的格式与show_index_recommendations()函数的相同,但包含所有存储会话的索引顾问建议,而show_index_recommendations()函数返回的结果集仅限于指定的会话。 |
使用索引顾问
使用索引顾问的示例中使用的表通过如下语句创建:
CREATE TABLE t( a INT, b INT );
INSERT INTO t SELECT s, 99999 - s FROM generate_series(0,99999) AS s;
ANALYZE t;
所生成的表包含以下各行:
a | b
-------+-------
0 | 99999
1 | 99998
2 | 99997
3 | 99996
.
.
.
99997 | 2
99998 | 1
99999 | 0
加载索引顾问插件后,索引顾问会分析所有SQL语句,并记录会话期间的所有索引编制建议:
- 如果您希望在不实际执行查询的情况下让索引顾问分析查询并提出索引编制建议,将EXPLAIN关键字作为SQL语句的前缀即可实现。
- 如果语句不带EXPLAIN关键字前缀,索引顾问将在语句执行期间分析语句,并将索引编制建议写入index_advisor_log表以供日后查看。