PostgreSQL 的统计收集器是否跟踪*所有*索引的使用情况?
Does PostgreSQL's Statistics Collector track *all* usage of indexes?
在接管一个相当复杂的数据库的 DBA 职责后,我想消除任何占用大量磁盘 space 但未被使用的索引。我 运行 以下内容,以识别未使用的索引,排序以优先考虑那些在磁盘上消耗最多 space 的索引:
SELECT
schemaname,
pg_stat_all_indexes.relname AS table,
pg_class.relname AS index,
pg_total_relation_size(oid) AS size,
idx_scan,
idx_tup_read,
idx_tup_fetch
FROM pg_class
JOIN pg_stat_all_indexes ON pg_stat_all_indexes.indexrelname = pg_class.relname
WHERE
relkind =('i')
ORDER BY size DESC
我有点惊讶有多少大索引似乎根本没有被使用——idx_scan 列的 0 就是证明。其中一些显然未使用的索引包括一个函数调用,它执行一些非常具体的事情(如下面的人为示例),并且似乎已设置为协助 API 功能。
--not real index
CREATE INDEX foo_transform_foo_name_idx
ON foo USING btree
(foo_transform_name(foo_name));
我的问题是统计收集器是否捕获了特定索引的所有 使用,即使这些索引是从 SQL 语言函数中扫描的,或者以其他方式?
这些索引从未被扫描过。但是,索引还有一些其他用途:
它们强制执行唯一性和其他约束
他们ANALYZE
收集索引表达式的统计数据
使用来自 my blog 的查询来查找您可以删除而不会产生任何负面影响的索引:
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;
在接管一个相当复杂的数据库的 DBA 职责后,我想消除任何占用大量磁盘 space 但未被使用的索引。我 运行 以下内容,以识别未使用的索引,排序以优先考虑那些在磁盘上消耗最多 space 的索引:
SELECT
schemaname,
pg_stat_all_indexes.relname AS table,
pg_class.relname AS index,
pg_total_relation_size(oid) AS size,
idx_scan,
idx_tup_read,
idx_tup_fetch
FROM pg_class
JOIN pg_stat_all_indexes ON pg_stat_all_indexes.indexrelname = pg_class.relname
WHERE
relkind =('i')
ORDER BY size DESC
我有点惊讶有多少大索引似乎根本没有被使用——idx_scan 列的 0 就是证明。其中一些显然未使用的索引包括一个函数调用,它执行一些非常具体的事情(如下面的人为示例),并且似乎已设置为协助 API 功能。
--not real index
CREATE INDEX foo_transform_foo_name_idx
ON foo USING btree
(foo_transform_name(foo_name));
我的问题是统计收集器是否捕获了特定索引的所有 使用,即使这些索引是从 SQL 语言函数中扫描的,或者以其他方式?
这些索引从未被扫描过。但是,索引还有一些其他用途:
它们强制执行唯一性和其他约束
他们
ANALYZE
收集索引表达式的统计数据
使用来自 my blog 的查询来查找您可以删除而不会产生任何负面影响的索引:
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;