为什么我的postgreSQL索引没有被使用?

时间:2012-07-30 08:04:12

标签: performance postgresql datetime indexing

当我使用以下查询时,响应时间非常糟糕(有时超过一分钟!)。

select * from cdr where start_time < now() - interval '4 hours' and final = 0 limit 50 

我正在尝试获取最终= 0且开始时间超过4小时的记录。 以下是我在桌子上的索引:

CREATE INDEX "cdr_Final_ix"
ON cdr
USING btree
(start_time , final );

以下是解释分析:

"Limit  (cost=0.00..167.81 rows=50 width=188) (actual time=64491.409..64650.635 rows=11 loops=1)"
"  ->  Seq Scan on cdr  (cost=0.00..749671.06 rows=223372 width=188) (actual time=64491.407..64650.625 rows=11 loops=1)"
"Filter: ((final = 0) AND (start_time < (now() - '04:00:00'::interval)))"
"Total runtime: 64650.690 ms"

任何帮助都会非常感激。谢谢,阿里

1 个答案:

答案 0 :(得分:3)

-- DROP SCHEMA tmp CASCADE;
-- CREATE SCHEMA tmp ;
SET search_path='tmp';

-- Generate some data
CREATE TABLE cdr
        ( start_time TIMESTAMP NOT NULL
        , final INTEGER
        );
INSERT INTO cdr (start_time,final)
SELECT gs, random() * 1000
FROM generate_series('2012-07-01 00:00:00', '2012-08-01 00:00:00', '1 s'::interval) gs
        ;
DROP INDEX "cdr_Final_ix";
CREATE INDEX "cdr_Final_ix"
ON cdr
USING btree
(start_time , final )
WHERE final = 0 -- partial index here
;

-- Do some data-massaging
-- UPDATE cdr
-- SET final = random() * 100
-- WHERE final = 0
-- AND random() < 0.2 ;

VACUUM ANALYZE cdr;

-- SET tuning to default (the worst possible)
SET random_page_cost = 4;
SET work_mem = 64;
SET effective_cache_size = 64;
-- SET shared_buffers = 64;

EXPLAIN ANALYZE
SELECT * from cdr
WHERE start_time < now() - interval '4 hours'
AND final = 0
ORDER BY start_time
LIMIT 50
        ;

结果:

                                                           QUERY PLAN                                                            
----------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.01..88.49 rows=50 width=12) (actual time=0.191..0.452 rows=50 loops=1)
   ->  Index Scan using "cdr_Final_ix" on cdr  (cost=0.01..4310.95 rows=2436 width=12) (actual time=0.188..0.321 rows=50 loops=1)
         Index Cond: ((start_time < (now() - '04:00:00'::interval)) AND (final = 0))
 Total runtime: 0.569 ms
(4 rows)