2

次のクエリを使用すると、応答時間が非常に遅くなります (場合によっては 1 分以上!)。

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

final=0 で starttime が 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"

どんな助けでも大歓迎です。ありがとう、アリ

4

1 に答える 1

4
-- 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)
于 2012-07-30T09:21:35.757 に答える