是否有工具或方法来分析Postgres,并确定应创建哪些缺少的索引,以及应删除哪些未使用的索引?我对SQLServer的“探查器”工具有一定的经验,但是我不知道Postgres附带的类似工具。
Answers:
我喜欢这样来查找丢失的索引:
SELECT
relname AS TableName,
to_char(seq_scan, '999,999,999,999') AS TotalSeqScan,
to_char(idx_scan, '999,999,999,999') AS TotalIndexScan,
to_char(n_live_tup, '999,999,999,999') AS TableRows,
pg_size_pretty(pg_relation_size(relname :: regclass)) AS TableSize
FROM pg_stat_all_tables
WHERE schemaname = 'public'
AND 50 * seq_scan > idx_scan -- more then 2%
AND n_live_tup > 10000
AND pg_relation_size(relname :: regclass) > 5000000
ORDER BY relname ASC;
这将检查是否有比索引扫描更多的序列扫描。如果表很小,它会被忽略,因为Postgres似乎更喜欢对它们进行顺序扫描。
上面的查询确实揭示了丢失的索引。
下一步将是检测缺少的组合索引。我想这并不容易,但可行。也许分析慢查询...我听说pg_stat_statements可以帮助...
SELECT relname, seq_scan-idx_scan AS too_much_seq, case when seq_scan-idx_scan>0 THEN 'Missing Index?' ELSE 'OK' END, pg_relation_size(relid::regclass) AS rel_size, seq_scan, idx_scan FROM pg_stat_all_tables WHERE schemaname='public' AND pg_relation_size(relid::regclass)>80000 ORDER BY too_much_seq DESC;
too_much_seq
正数很大时,您应该关注。
::regclass
不适用于大写标识符@Mr。Muskrat有一个很好的解决方案,也可以('"' || relname || '"')::regclass
代替使用。
在确定丢失索引的方法上。但是,有一些计划使它在将来的发行版中变得更容易,例如伪索引和机器可读的EXPLAIN。
当前,您将需要EXPLAIN ANALYZE
执行效果不佳的查询,然后手动确定最佳路线。一些日志分析器(例如pgFouine)可以帮助确定查询。
至于未使用的索引,可以使用以下类似内容来帮助识别它们:
select * from pg_stat_all_indexes where schemaname <> 'pg_catalog';
这将有助于识别已读取,已扫描,已获取的元组。
您可以在下面的查询中查找索引使用情况和索引大小:
SELECT
pt.tablename AS TableName
,t.indexname AS IndexName
,to_char(pc.reltuples, '999,999,999,999') AS TotalRows
,pg_size_pretty(pg_relation_size(quote_ident(pt.tablename)::text)) AS TableSize
,pg_size_pretty(pg_relation_size(quote_ident(t.indexrelname)::text)) AS IndexSize
,to_char(t.idx_scan, '999,999,999,999') AS TotalNumberOfScan
,to_char(t.idx_tup_read, '999,999,999,999') AS TotalTupleRead
,to_char(t.idx_tup_fetch, '999,999,999,999') AS TotalTupleFetched
FROM pg_tables AS pt
LEFT OUTER JOIN pg_class AS pc
ON pt.tablename=pc.relname
LEFT OUTER JOIN
(
SELECT
pc.relname AS TableName
,pc2.relname AS IndexName
,psai.idx_scan
,psai.idx_tup_read
,psai.idx_tup_fetch
,psai.indexrelname
FROM pg_index AS pi
JOIN pg_class AS pc
ON pc.oid = pi.indrelid
JOIN pg_class AS pc2
ON pc2.oid = pi.indexrelid
JOIN pg_stat_all_indexes AS psai
ON pi.indexrelid = psai.indexrelid
)AS T
ON pt.tablename = T.TableName
WHERE pt.schemaname='public'
ORDER BY 1;
脚本有多个链接,可帮助您在PostgreSQL Wiki上找到未使用的索引。基本技术是查看pg_stat_user_indexes
并查找其中idx_scan
,该索引用于回答查询的次数为零或至少非常低。如果应用程序已更改,并且以前可能没有使用以前的索引,则有时您必须运行pg_stat_reset()
以将所有统计信息恢复为0,然后收集新数据;您可以保存所有内容的当前值并计算一个增量,以解决此问题。
尚无任何好的工具可以建议缺少索引。一种方法是使用pgFouine或pqa等查询日志分析工具记录正在运行的查询,并分析哪些查询需要花费很长时间才能运行。有关更多信息,请参见“记录困难的查询”。
另一种方法是查看pg_stat_user_tables
并查找对它们有大量顺序扫描的表,这些表seq_tup_fetch
很大。使用索引时,idx_fetch_tup
计数会增加。当一个表的索引编制得不够好,无法回答对该表的查询时,这可能会提示您。
实际弄清楚应该在哪些列上建立索引?这通常会再次导致查询日志分析。
可以通过在postgres控制台中使用以下查询来找到它
use db_name
select * from pg_stat_user_indexes;
select * from pg_statio_user_indexes;
有关更多详细信息,请参见https://www.postgresql.org/docs/current/monitoring-stats.html
对于PostgreSQL 9.4 +,PoWA似乎是一个有趣的工具。它收集统计数据,将其可视化并建议索引。它使用pg_stat_statements
扩展名。
PoWA是PostgreSQL Workload Analyzer,它收集性能统计数据并提供实时图表,以帮助监视和调整PostgreSQL服务器。它类似于Oracle AWR或SQL Server MDW。
CREATE EXTENSION pgstattuple;
CREATE TABLE test(t INT);
INSERT INTO test VALUES(generate_series(1, 100000));
SELECT * FROM pgstatindex('test_idx');
version | 2
tree_level | 2
index_size | 105332736
root_block_no | 412
internal_pages | 40
leaf_pages | 12804
empty_pages | 0
deleted_pages | 13
avg_leaf_density | 9.84
leaf_fragmentation | 21.42