У меня есть четыре стола; два для текущих данных, два для архивных данных. Одна из архивных таблиц содержит десятки миллионов строк. Все таблицы имеют несколько узких индексов и очень похожи.postgres не использует индекс для SELECT COUNT (*) для большой таблицы
Учитывая следующие запросы:
SELECT (SELECT COUNT(*) FROM A)
UNION SELECT (SELECT COUNT(*) FROM B)
UNION SELECT (SELECT COUNT(*) FROM C_LargeTable)
UNION SELECT (SELECT COUNT(*) FROM D);
А, В и D выполняют сканирование индекса. C_LargeTable использует seq scan
, и запрос занимает около 20 секунд. Таблица D имеет также миллионы строк, но составляет лишь около 10% от размера C_LargeTable
Если я затем изменяю свой запрос на выполнение, используя следующую логику, которая достаточно сужает количество отсчетов, я все равно получаю те же результаты, используется индекс и запрос занимает около 5 секунд, или 1/4th времени
...
SELECT (SELECT COUNT(*) FROM C_LargeTable WHERE idx_col < 'G')
+ (SELECT COUNT(*) FROM C_LargeTable WHERE idx_col BETWEEN 'G' AND 'Q')
+ (SELECT COUNT(*) FROM C_LargeTable WHERE idx_col > 'Q')
...
Это не имеет смысл для меня, чтобы иметь I/O накладные расходы полного сканирования таблицы для подсчета, когда отлично хорошо существуют индексы, и есть первичный ключ покрытия, который обеспечивал бы уникальность. Мое понимание postgres заключается в том, что PRIMARY KEY
не похож на индекс кластеризации SQL Server, поскольку он определяет сортировку, но он неявно создает индекс btree для обеспечения уникальности, который, как я полагаю, должен требовать значительно меньше ввода-вывода, чем полное сканирование таблицы ,
Является ли это потенциально индикатором оптимизации, которую может потребоваться для организации данных в C_LargeTable?
Какую версию Postgres вы используете? Только индекс 9.2 и выше сможет использовать индекс. Это также FAQ: https://wiki.postgresql.org/wiki/FAQ#Why_is_.22SELECT_count.28.2A.29_FROM_bigtable.3B.22_slow.3F –
Я запускаю 9.3. Ваш ответ объяснил, почему это происходит. Есть ли рекомендация сделать что-то еще? Я попытался установить enable_seqcan = false, и он, похоже, не дал большой разницы в производительности (после этого я вернул его в true). –
Вы также можете прочитать: https://wiki.postgresql.org/wiki/Slow_Query_Questions –