删除不可用的索引更好吗?

问题描述 投票:1回答:2

以下查询的结果向我显示了索引统计历史记录。如果删除在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;
sql database postgresql indexing postgresql-9.5
2个回答
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;

[您需要考虑索引除了加速WHEREORDER BY子句外还有其他用途:

  • 许多约束由索引实现,例如主键。

  • 表达式索引使PostgreSQL收集索引表达式的统计信息,这有助于优化程序。

有关详细信息,请参见my blog


3
投票

当然,您应该删除不使用的索引。索引可加快某些操作的速度,但要付出一定的代价-每次插入,删除或进行某些更新时,都需要对其进行更新。

Here是关于维护更新时附加索引,删除时为here和插入时为here的开销的好文章。例如,插入具有2个索引的表的时间几乎是具有1个索引的同一表的时间的两倍。

© www.soinside.com 2019 - 2024. All rights reserved.