以下查询的结果向我显示了索引统计历史记录。删除在0
返回TotalNumberOfScan
值的索引会更好吗?
SELECT
pt.tablename AS TableName
,t.indexname AS IndexName
,pc.reltuples 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
,t.idx_scan AS TotalNumberOfScan
,t.idx_tup_read AS TotalTupleRead
,t.idx_tup_fetch 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;
答案 0 :(得分:4)
当然,您应该删除不使用的索引。索引可以加快某些操作的速度,但是要付出一定的代价-每次插入,删除或进行某些更新时,都需要对其进行更新。
Here是一篇很棒的文章,内容涉及维护更新时附加索引,删除时here和插入时here的维护成本。例如,插入具有2个索引的表的时间几乎是具有1个索引的同一表的时间的两倍。
答案 1 :(得分:2)
这是我的黄金标准查询,用于查找所有无用的索引:
SELECT s.schemaname,
s.relname AS tablename,
s.indexrelname AS indexname,
pg_relation_size(s.indexrelid) AS index_size
FROM pg_catalog.pg_stat_user_indexes s
JOIN pg_catalog.pg_index i ON s.indexrelid = i.indexrelid
WHERE s.idx_scan = 0 -- has never been scanned
AND 0 <>ALL (i.indkey) -- no index column is an expression
AND NOT i.indisunique -- is not a UNIQUE index
AND NOT EXISTS -- does not enforce a constraint
(SELECT 1 FROM pg_catalog.pg_constraint c
WHERE c.conindid = s.indexrelid)
ORDER BY pg_relation_size(s.indexrelid) DESC;
您需要考虑索引除了加速WHERE
和ORDER BY
子句外还有其他用途:
许多约束都是通过索引实现的,例如主键。
表达式索引使PostgreSQL收集索引表达式的统计信息,这有助于优化程序。
有关详细信息,请参见my blog。