在PostgreSQL 9.4.0数据库中,我有一个包含22个索引的繁忙表,这些索引大于表中的实际数据。 由于大多数这些索引都是针对几乎完全为NULL的列,我一直在尝试用部分索引替换其中的一些。
其中一列是:auto_decline_at没有时区的时间戳。在总共5457088行中有5453085个NULLS。
正在使用部分索引替换,但根据统计信息,旧索引仍在使用中,因此我不敢删除它。 从pg_tables中选择我看:
tablename | indexname | num_rows | table_size | index_size | unique | number_of_scans | tuples_read | tuples_fetched
-----------+---------------------------------------+-------------+------------+------------+--------+-----------------+-------------+----------------
jobs | index_jobs_on_auto_decline_at | 5.45496e+06 | 1916 MB | 3123 MB | N | 17056009 | 26506058607 | 26232155810
jobs | index_jobs_on_auto_decline_at_partial | 5.45496e+06 | 1916 MB | 120 kB | N | 6677 | 26850779 | 26679802
几分钟后:
tablename | indexname | num_rows | table_size | index_size | unique | number_of_scans | tuples_read | tuples_fetched
-----------+---------------------------------------+-------------+------------+------------+--------+-----------------+-------------+----------------
jobs | index_jobs_on_auto_decline_at | 5.45496e+06 | 1916 MB | 3124 MB | N | 17056099 | 26506058697 | 26232155900
jobs | index_jobs_on_auto_decline_at_partial | 5.45496e+06 | 1916 MB | 120 kB | N | 6767 | 27210639 | 27039623
因此,number_of_scans正在增加。 索引定义:
"index_jobs_on_auto_decline_at" btree (auto_decline_at)
"index_jobs_on_auto_decline_at_partial" btree (auto_decline_at) WHERE auto_decline_at IS NOT NULL
我在日志中看到的唯一相关查询遵循以下模式:
SELECT "jobs".* FROM "jobs" WHERE (jobs.pending_destroy IS NULL OR jobs.pending_destroy = FALSE) AND "jobs"."deleted_at" IS NULL AND (state = 'assigned' AND auto_decline_at IS NOT NULL AND auto_decline_at < '2015-08-17 06:57:22.325324')
EXPLAIN ANALYZE为我提供了以下计划,该计划使用了预期的部分索引:
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------
Index Scan using index_jobs_on_auto_decline_at_partial on jobs (cost=0.28..12.27 rows=1 width=648) (actual time=22.143..22.143 rows=0 loops=1)
Index Cond: ((auto_decline_at IS NOT NULL) AND (auto_decline_at < '2015-08-17 06:57:22.325324'::timestamp without time zone))
Filter: (((pending_destroy IS NULL) OR (NOT pending_destroy)) AND (deleted_at IS NULL) AND ((state)::text = 'assigned'::text))
Rows Removed by Filter: 3982
Planning time: 2.731 ms
Execution time: 22.179 ms
(6 rows)
我的问题: