У меня очень простой запрос SQL:
SELECT COUNT(DISTINCT x) FROM table;
В моей таблице около 1,5 миллионов строк. Этот запрос выполняется довольно медленно; занимает около 7,5 с, по сравнению с
SELECT COUNT(x) FROM table;
что занимает около 435 мс. Есть ли способ изменить мой запрос, чтобы повысить производительность? Я пытался группировать и делать регулярные подсчеты, а также поставить индекс на х; оба имеют одинаковое время выполнения 7.5 с.
performance
postgresql
count
distinct
ferson2020
источник
источник
\d
выводpsql
- хороший) и укажите столбец, с которым у вас возникли проблемы. Было бы хорошо увидетьEXPLAIN ANALYZE
оба запроса.Ответы:
Вы можете использовать это:
Это намного быстрее чем:
источник
COUNT(DISTINCT())
выполняет сортировку, будет определенно полезно иметь индексcolumn_name
особенно с относительно небольшим количествомwork_mem
(где хеширование приведет к относительно большому количеству пакетов). С тех пор не всегда плохо использовать COUNT (DISTINCT () _, не так ли?Count(column)
только ненулевые значения.count(*)
считает строки. Таким образом, первый / более длинный также будет считать нулевую строку (один раз). Выберите, чтобыcount(column_name)
они вели себя одинаково.Полученные результаты:
Тот же план, что и для CTE, возможно, также может быть разработан другими методами (оконные функции).
источник
Если ваш запрос
count(distinct(x))
значительно медленнее, чемcount(x)
вы, вы можете ускорить этот запрос, поддерживая значения х значений в другой таблице, напримерtable_name_x_counts (x integer not null, x_count int not null)
, используя триггеры. Но ваша производительность записи пострадает, и если вы обновите несколькоx
значений в одной транзакции, вам нужно будет сделать это в некотором явном порядке, чтобы избежать возможного тупика.источник
Я также искал тот же ответ, потому что в какой-то момент мне нужно было total_count с различными значениями наряду с лимитом / смещением .
Потому что это немного сложно сделать - получить общий счет с различными значениями вместе с лимитом / смещением. Обычно сложно получить общий счет с лимитом / смещением. Наконец я получил способ сделать -
SELECT DISTINCT COUNT(*) OVER() as total_count, * FROM table_name limit 2 offset 0;
Производительность запросов также высока.
источник