我在文本列上有一个btree索引,它包含一个状态标记 - 包含此字段的查询比没有它的查询运行速度慢100倍 - 我该怎么做才能加快速度?它的基数相当低 - 我尝试过hash,btree有text_pattern_ops和部分索引 - 整理是utf8。没有状态索引的查询大约在同一时间运行...
db=# show lc_collate; lc_collate ------------- en_US.UTF-8 (1 row) db=# drop index job_status_idx; DROP INDEX db=# CREATE INDEX job_status_idx ON job(status text_pattern_ops); CREATE INDEX db=# select status, count(*) from job group by 1; status | count -------------+-------- pending | 365027 booked | 37515 submitted | 20783 cancelled | 191707 negotiating | 30 completed | 241339 canceled | 56 (7 rows) db=# explain analyze SELECT key_ FROM "job" WHERE active = true and start > '2014-06-15T19:23:23.691670'::timestamp and status = 'completed' ORDER BY start DESC OFFSET 450 LIMIT 150; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------- Limit (cost=5723.07..7630.61 rows=150 width=51) (actual time=634.978..638.086 rows=150 loops=1) -> Index Scan Backward using job_start_idx on job (cost=0.42..524054.39 rows=41209 width=51) (actual time=625.776..637.023 rows=600 loops=1) Index Cond: (start > '2014-06-15 19:23:23.69167'::timestamp without time zone) Filter: (active AND (status = 'completed'::text)) Rows Removed by Filter: 94866 Total runtime: 638.358 ms (6 rows) db=# explain analyze SELECT key_ FROM "job" WHERE active = true and start > '2014-06-15T19:23:23.691670'::timestamp ORDER BY start DESC OFFSET 450 LIMIT 150; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- Limit (cost=1585.61..2114.01 rows=150 width=51) (actual time=4.620..6.333 rows=150 loops=1) -> Index Scan Backward using job_start_idx on job (cost=0.42..523679.58 rows=148661 width=51) (actual time=0.080..5.271 rows=600 loops=1) Index Cond: (start > '2014-06-15 19:23:23.69167'::timestamp without time zone) Filter: active Total runtime: 6.584 ms (5 rows)
答案 0 :(得分:1)
这是您的查询:
SELECT key_
FROM "job"
WHERE active = true and
start > '2014-06-15T19:23:23.691670'::timestamp and
status = 'completed'
ORDER BY start DESC
OFFSET 450 LIMIT 150;
status
上的索引不是很有选择性。我会建议一个综合指数:
CREATE INDEX job_status_idx ON job(status text_pattern_ops, active, start, key_)
这是一个覆盖索引,它应该更好地匹配where
子句。