我使用此代码段来检测丢失的索引:
https://stackoverflow.com/a/12818168/633961
例子:
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;
结果:
tablename | totalseqscan | totalindexscan | tablerows | tablesize
----------+--------------+----------------+-----------+----------
mytable | 112,479 | 2,978,344 | 1,293,536 | 1716 MB
我很好奇 - 我想看看哪些 SQL 语句实际上对表进行了序列扫描mytable
。
有没有办法让 PostgreSQL 在对该表进行顺序扫描时发出警告?
我认为做到这一点的唯一方法是使用auto_explain模块并在语句慢于例如一秒时启用执行计划的转储。
该计划将写入 Postgres日志文件
然后你可以有一个作业来监控日志文件并在序列扫描是计划的一部分时采取行动。
不应该不惜一切代价避免 Seq 扫描。它通常是获得结果的最快方法。
我会专注于 Seq Scans 的计划,但只是尝试查找(然后修复)缓慢的查询。
为了分析日志文件,你想在pgbadger上有一个日志,或者你可以使用POWA来实时监控你的服务器