PostgreSQL: COUNT (*) використовує послідовне сканування, а не індекс


12

Чому PostgreSQL послідовно сканує таблицю для COUNT(*)запиту, хоча там є дуже маленький та індексований первинний ключ?

Відповіді:


16

На офіційних сторінках вікі дати відповідь на цей питання :

[...] Причина, чому це повільно, пов'язана з реалізацією MVCC у PostgreSQL. Той факт, що в декількох транзакціях можна побачити різні стани даних, означає, що "COUNT (*)" не може бути простим способом узагальнення даних по всій таблиці; PostgreSQL у певному сенсі повинен пройти всі рядки. Зазвичай це призводить до послідовного сканування зчитування інформації про кожен рядок таблиці. [...]

Крім того, ви можете спробувати ANALYZE для відновлення інформації для планувальника запитів.

Ви повинні досягти кращої продуктивності, використовуючи, COUNT(an uniquly indexed field)але якщо це дуже велике значення, єдиний спосіб зробити це сканування послідовності.

Якщо вам потрібні дуже швидкі номери і ви не боїтеся запитувати схему, ви можете зробити наступне

SELECT reltuples FROM pg_class WHERE oid = 'your_table'::regclass

Але не покладайтеся на ці значення, оскільки це лише "приблизна" (хоча часто і точна) кількість кортежів у таблиці.


Я не думаю, що це правильно. Я ніде нічого не читав, де COUNT(pk)покращуватиметься продуктивність. Я думаю, що це завжди буде робити
послідовне

1
Без пункту де ви правильні, буде виконуватися перевірка послідовності. Якщо достатньо вибрати місце, де в пункті postgresql МОЖЕ використовуватись індекс, але майте на увазі, ВІДПОВІДНО повернутися до таблиці, щоб перевірити видимість кортежів, про які він звітує.
Скотт Марлоу

Ще один спосіб отримати приблизну кількість рядків, яку мені легше запам'ятати, - це EXPLAIN SELECT * from your_table;. Це не виконає запит. Вихід включає rows=…з розрахунковою кількістю рядків.
Свен Марнах
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.