#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 КБ).
Всегда тестируйте с реалистичными объемами данных. Это избавит вас от некоторой боли позже.