Самый быстрый способ узнать, какие уникальные даты находятся в поле отметки времени таблицы? - PullRequest
2 голосов
/ 18 мая 2011

У меня есть таблица с миллиардами строк.В поле «Записано» есть ежедневные разделы, которые являются «меткой времени без часового пояса».Я хочу знать, какие дни в настоящее время в таблице.Я знаю, что мог бы сделать что-то вроде:

SELECT recorded::date
FROM table
GROUP BY 1;

Что в идеале должно сработать, но объяснение этого довольно велико и указывает, что работа займет довольно много времени ... если это лучшее, что я могуЯ могу принять это (и мы могли бы следить за данными по мере их поступления), но мне было интересно, может ли быть более эффективный способ сделать это, учитывая, что у меня есть ежедневное разбиение?

Ответы [ 2 ]

2 голосов
/ 18 мая 2011

Вы можете создать индекс примерно так:

create index your_index_name
on table (date_trunc('day', recorded))

В моем тесте PostgreSQL 9. что-то использовало последовательное сканирование перед добавлением индекса, последовательное сканирование после простого индексирования столбца «записано» и сканирование индекса после индексации с помощью date_trunc (). Выбор строк за один день занял 66 мс без индекса, 68 мс с простым индексом и 13 мс с индексом с использованием date_trunc ().

Ожидается, что при создании миллиардов строк создание этого индекса займет несколько минут. (Кашель)

1 голос
/ 18 мая 2011

Здесь очень похожая тема:

Медленный выбор отдельного запроса на postgres

Если вы знаете минимальные / максимальные даты, лучше выполнить запрос по списку дат, чем выполнять последовательное сканирование всей таблицы. Предполагая, что у вас есть индекс для записи, что-то, что выглядит так, должно быть быстрее:

with days as (
select date_trunc('day', min(recorded))::date + k * interval '1 day' as day
from records,
     generate_series(0,
                    (select date_trunc('day', max(recorded))::date
                            - date_trunc('day', min(recorded)::date
                    from records
     )) as k
)
select day
from days
where exists (
      select 1
      from records
      where day <= recorded and recorded < day + interval '1 day'
      );

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

...