PostgreSQL перебирает миллионы записей? - PullRequest
0 голосов
/ 27 апреля 2019

У меня есть таблица 'location_signals' с около 250 миллионами записей с индексом в поле ID.Таблица имеет идентификатор, метку времени, широту и долготу (и пару других столбцов, которые не используются).Каждый идентификатор может иметь тысячи записей Lat / Lon с разными временными метками.У меня есть подпрограмма, которая передает идентификатор, она выбирает все записи для этого идентификатора и возвращает обратно круг с самой высокой концентрацией широты / долготы.

Вышеописанное сработало очень хорошо, когда у нас было десять тысяч записей, но когда мы импортировали больше данных, он больше не может их обрабатывать.Логика следующая:

  • Выбор уникальных идентификаторов с помощью «выбора идентификатора из группы location_signals по идентификатору» (ограничение только 1500), одна из проблем заключается в том, что метка времени данных не в идеальном форматетак что это делается:

       SELECT TO_TIMESTAMP(timestamp, 'MM/DD/YY HH24:MI') AS ts, * 
        FROM  location_signals 
        WHERE (
        extract(hour from TO_TIMESTAMP(timestamp, 'MM/DD/YY HH24:MI')) > '18' 
        OR  extract(hour from TO_TIMESTAMP(timestamp, 'MM/DD/YY HH24:MI')) < '06'  
        )
        AND \"DID\" = '$did'
    
        LIMIT 1500
    
  • Передача идентификаторов в рутину

Я считаю, что проблема заключается в том, что циклы по миллионам и томуметка времени, или, может быть, что-то еще.Любой вклад будет высоко оценен.Может быть, делать вещи партиями тоже?Если да, то как?

1 Ответ

5 голосов
/ 27 апреля 2019

Вы должны действительно исправить свой столбец timestamp, чтобы он был реальной отметкой времени. Хранение значения даты / времени в виде строк - очень плохая идея. Называя столбцы так, как будто они были сохранены как правильный тип данных - ну, на мой взгляд, это граничит с халатностью.

Поскольку вы хотите выполнять поиск по временному диапазону, вы можете создать индекс для выражения:

create index idx_location_signals_id_time on location_signals(did, to_timestamp(timestamp, 'MM/DD/YY HH24:MI')::time));

Тогда вы можете выразить свою where логику как:

where did = ? and
      (to_timestamp(timestamp, 'MM/DD/YY HH24:MI')::time >= '19:00:00'::time or
       to_timestamp(timestamp, 'MM/DD/YY HH24:MI')::time < '06:00:00'::time
      )

Это должно использовать индекс для полного выражения.

...