0

這是我measurement_pm2_5表:爲什麼這個查詢很慢? - PostgreSQL的 - 從串行,TIMESTAMP和NUMERIC選擇(6,2)

CREATE TABLE public.measurement_pm2_5 (
    sensor_id SERIAL, 
    measurement_time TIMESTAMP WITHOUT TIME ZONE NOT NULL, 
    measurement_value NUMERIC(6,2) NOT NULL, 
    CONSTRAINT measurement_pm2_5_sensor_id_fkey FOREIGN KEY (sensor_id) 
    REFERENCES public.sensor(id) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION 
    NOT DEFERRABLE 
) 
WITH (oids = false); 

這是我的查詢:

select sensor_id, measurement_time, measurement_value 
FROM "public"."measurement_pm10" p, 
     (values(64,1476094463,1476116063),(129,1476094463,1476116063),(66,1476094463,1476116063),(130,1476094463,1476116063),(3,1476094463,1476116063),(131,1476094463,1476116063),(132,1476094463,1476116063),(133,1476094463,1476116063),(134,1476094463,1476116063),(135,1476094463,1476116063),(136,1476094463,1476116063),(137,1476094463,1476116063),(138,1476094463,1476116063),(139,1476094463,1476116063),(142,1476094463,1476116063),(17,1476094463,1476116063),(18,1476094463,1476116063),(19,1476094463,1476116063),(148,1476094463,1476116063),(94,1476094463,1476116063),(96,1476094463,1476116063),(101,1476094463,1476116063),(58,1476094463,1476116063),(59,1476094463,1476116063),(60,1476094463,1476116063),(63,1476094463,1476116063)) as t(sensor,t1,t2) 
WHERE p.sensor_id = t.sensor 
    AND measurement_time BETWEEN to_timestamp(t.t1) AND to_timestamp(t.t2); 

它需要爲至16秒數據庫來執行它並給出響應。 它返回約3k行。一般來說,這個表中有260k行。

有什麼辦法讓它更快?更快我的意思是在不到一秒鐘內執行它?

我使用AWS的免費層的PostgreSQL數據庫。

EXPLAIN (ANALYZE, BUFFER)

Hash Join (cost=0.65..8056.77 rows=5835 width=18) (actual time=15308.237..16039.319 rows=3035 loops=1) 
    Hash Cond: (p.sensor_id = "*VALUES*".column1) 
    Join Filter: ((p.measurement_time >= to_timestamp(("*VALUES*".column2)::double precision)) AND (p.measurement_time <= to_timestamp(("*VALUES*".column3)::double precision))) 
    Rows Removed by Join Filter: 182836 
    Buffers: shared hit=2330 
    -> Seq Scan on measurement_pm10 p (cost=0.00..5538.74 rows=321174 width=18) (actual time=0.007..1657.386 rows=321229 loops=1) 
     Buffers: shared hit=2327 
    -> Hash (cost=0.33..0.33 rows=26 width=12) (actual time=0.018..0.018 rows=26 loops=1) 
     Buckets: 1024 Batches: 1 Memory Usage: 10kB 
     -> Values Scan on "*VALUES*" (cost=0.00..0.33 rows=26 width=12) (actual time=0.002..0.010 rows=26 loops=1) 
Planning time: 0.560 ms 
Execution time: 16040.164 ms 
+1

可能是相關的:http://stackoverflow.com/a/39246869/251311但是如果你提供了'EXPLAIN ANALYZE',那將會很好。 PS:你真的在桌上沒有索引嗎? – zerkms

+0

@zerkms感謝您鏈接的問題。您可以幫助我加入CTE來構建查詢嗎?我不確定我應該把自己的條件放在哪裏。我用'EXPLAIN(ANALYZE,BUFFER)'更新了我的帖子。 – Defozo

+1

那麼,你至少需要爲'sensor_id'列添加一個索引(因爲它是一個FK),然後顯示它的更新計劃。 – zerkms

回答

0

創建的時間戳的非聚集索引,你正在根據時間戳篩選值。這肯定會有幫助

+1

Postgres中的所有索引都是「非聚集的」 –