gpt4 book ai didi

postgresql - 删除未使用的索引

转载 作者:行者123 更新时间:2023-11-29 12:52:38 24 4
gpt4 key购买 nike

我运行这个查询来检查我的数据库中是否有一些未使用的索引。

select 
t.tablename AS "relation",
indexname,
c.reltuples AS num_rows,
pg_relation_size(quote_ident(t.tablename)::text) AS table_size,
pg_relation_size(quote_ident(indexrelname)::text) AS index_size,
idx_scan AS number_of_scans,
idx_tup_read AS tuples_read,
idx_tup_fetch AS tuples_fetched
FROM pg_tables t
LEFT OUTER JOIN pg_class c ON t.tablename=c.relname
LEFT OUTER JOIN
( SELECT c.relname AS ctablename, ipg.relname AS indexname, x.indnatts AS number_of_columns, psai.idx_scan, idx_tup_read, idx_tup_fetch, indexrelname, indisunique FROM pg_index x
JOIN pg_class c ON c.oid = x.indrelid
JOIN pg_class ipg ON ipg.oid = x.indexrelid
JOIN pg_stat_all_indexes psai ON x.indexrelid = psai.indexrelid )
AS foo
ON t.tablename = foo.ctablename
WHERE t.schemaname='public'
and idx_scan = 0
ORDER BY
--1,2
--6
5 desc
;

我得到了很多行,其中这些字段都是零:

number_of_scans,
tuples_read,
tuples_fetched

这是否意味着我可以放弃它们?元数据是否有可能已过时?如何检查?

我正在使用 9.6 版的 Postgres

最佳答案

您的查询遗漏了一些不需要扫描索引的用途:

  • 他们执行主键、唯一性和排除约束

  • 它们影响统计数据收集(对于“表达索引”)

这是我来自 my blog post 的黄金标准查询:

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 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;

自从重置统计信息后,此处显示的任何内容都未被使用,可以安全删除。

有几点需要注意:

  • 统计信息收集必须运行(查找“统计信息收集器”进程并查看日志中是否有关于“陈旧统计信息”的警告)

  • 针对您的生产数据库运行查询

  • 如果您的程序在许多站点上运行,请在所有站点上尝试(不同的用户有不同的使用模式)

关于postgresql - 删除未使用的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50351169/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com