0

Это мой measurement_pm2_5 стол:Почему этот запрос настолько медленный? - PostgreSQL - выбор из SERIAL, 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 строк. Как правило, в этой таблице содержится 260 тыс. Строк.

Есть ли способ сделать это быстрее? Быстрее я хочу выполнить его менее чем за секунду?

Я использую базу данных PostgreSQL бесплатного уровня AWS.

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 –