Чому підрахунок (*) повільний, коли пояснення знає відповідь?


14

Цей запит: select count(*) from planner_eventзапускати потрібно дуже багато часу - так довго я здався і вбив його, перш ніж він закінчився. Однак, коли я запускаю explain select count(*) from planner_event, я бачу стовпчик у висновку із кількістю рядків (14м).

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


COUNT (*) без причини WHERE спричинить сканування таблиці в двигуні InnoDB. MyISAM може доставити підрахунок безпосередньо, оскільки COUNT зберігається у файлі de header із таблиці.
Raymond Nijland

Відповіді:


16

Поясніть, використовуючи раніше зібрану статистику (використовується оптимізатором запитів). Рухаємося select count(*)зчитує блок даних КОЖЕН.

Ось дешевий спосіб отримати приблизну кількість рядків:

select TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME='planner_event';

Навіть якщо ви це зробили select count(id), це може зайняти дуже багато часу, якщо ви не маєте вторинний індекс id(також якщо припустити id, що це ПЕРШИЙ КЛЮЧ). Оскільки всі дані (включаючи дані про рядки) зберігаються в індексах B-Tree, виконання A select count(PK_COLUMN)все ще є значним обсягом IO (потрібно прочитати всі сторінки даних). Якщо у вас є вторинний індекс у полі PK, він зможе виконати менше вводу-виводу для підрахунку.


I_S.TABLES дає вам ту саму оцінку, що і EXPLAINвам.
Рік Джеймс

Запит відсутній AND TABLE_SCHEMA='my_database', інакше ви отримаєте кілька результатів, якщо у вас буде однакова таблиця в іншій базі даних.
cz

3

Поясніть, отримує число з деяких "статистичних даних", які використовуються для оцінки речей для Оптимізатора. Це число може бути далеко не правильним - іноді я бачу, що воно більше, ніж коефіцієнт 2 (вищий або нижчий), ніж точне значення.

Виконуючи COUNT(*)таблицю InnoDB, слід сканувати таблицю, щоб уникнути запису рахунків, які зайняті вставкою / видаленням інших з'єднань, але ще не "здійснені". Насправді, це досить добре, щоб зробити повне сканування на якомусь індексі, не обов'язково цілій таблиці (яка містить цей PRIMARY KEY).

Скільки оперативної пам’яті у вас є? Яка цінність innodb_buffer_pool_size? Це може допомогти, якби це було близько 70% оперативної пам’яті.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.