Индекс временных МЕТОК Postgres и производительность запросов

#postgresql #indexing #timestamp

#postgresql #индексирование #временная метка

Вопрос:

У меня есть эта таблица:

 CREATE TABLE IF NOT EXISTS CHANGE_REQUESTS (
    ID             UUID PRIMARY KEY,
    FIELD_ID             INTEGER NOT NULL,
    LAST_CHANGE_DATE    TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
);
 

И я всегда буду выполнять один и тот же запрос к нему:

 select * from change_requests where last_change_date > now() - INTERVAL '10 min';
 

Размер таблицы в среднем будет составлять от 750 тыс. до 1 млн. строк.

Мой вопрос в том, как я могу убедиться, что запрос всегда выполняется очень быстро? Я подумываю о добавлении индекса last_change_date , но я не уверен, что это что-нибудь даст. Я попробовал это (только с 1 строкой в таблице прямо сейчас) и получил это объяснение:

 create index change_requests__dt_index
    on change_requests (last_change_date);
 
 Seq Scan on change_requests  (cost=0.00..1.02 rows=1 width=28)
  Filter: (last_change_date > (now() - '00:10:00'::interval))
 

Похоже, что он вообще не использует индекс.

Действительно ли этот индекс поможет? Если нет, что еще я мог сделать? Спасибо!

Комментарии:

1. Всего одна строка — это немного, попробуйте еще раз с (намного) большим количеством строк. В целом ваш индекс хорош для поддержки запроса. Вы могли бы попробовать и посмотреть, сможете ли вы даже улучшить его, указав индекс (last_change_date, id, field_id)`. Тогда на весь запрос можно было бы ответить только индексом.

2. Да, я подумал, что 1 строка не покажет мне, насколько быстро это будет на самом деле, но разве в ней хотя бы не упоминается, что она использует индекс? Что касается включения индекса (last_change_date, id, field_id), не могли бы вы объяснить, что это будет делать? На самом деле я никогда не выполняю поиск по какому-либо столбцу, кроме last_change_date, так что будет делать добавление этих других полей в индекс?

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

4. Интересно, хорошо. Я не знал, что при принятии решения об использовании индекса учитывается количество строк, спасибо за информацию. На самом деле я только что сгенерировал 1 миллион строк порциями по 250 тысяч за раз, и, наконец, когда я набрал 1 миллион строк в таблице, он изменил объяснение, чтобы начать использовать индекс. Большое спасибо за помощь!

5. Иногда вы можете использовать SET enable_seqscan = OFF;

Ответ №1:

Ваш индекс идеально подходит для этой задачи. Вы видите последовательное сканирование в плане выполнения, потому что у вас нет реального объема тестовых данных в таблице, а для очень маленьких таблиц накладные расходы на использование индекса не стоят усилий (вам пришлось бы обрабатывать больше блоков базы данных размером 8 КБ).

Всегда тестируйте с реалистичными объемами данных. Это избавит вас от некоторой боли позже.