慢postgres文本列查询

时间:2014-07-16 01:16:15

标签: postgresql postgresql-9.3

我在文本列上有一个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)

1 个答案:

答案 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子句。