Звідки оптимізатор запитів MySQL читає статистику індексу?


14

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


+1 для цього хорошого запитання, оскільки розробники та DBA повинні зробити паузу та продумати, як збираються та зберігаються статистичні дані про індекси.
RolandoMySQLDBA

Для довідки, з веб-сайту документації на mysql: < dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html >> ANALYZE TABLEвизначає індексну кардинальність (як відображено у стовпці SHOW INDEXвиводу Cardinality ), роблячи вісім випадкових занурень до кожного дерев індексу та відповідно оновлення оцінок кардинальності індексу. Оскільки це лише оцінки, неодноразові запуски таблиці АНАЛІЗУ можуть створювати різні числа. Це робить ANALYZE TABLEшвидко таблицю InnoDB, але не на 100% точну, оскільки вона не враховує всіх рядків.
Чень Сі

Відповіді:


6

Прямою відповіддю на це була б

інформація_schema.statistics

mysql> desc information_schema.statistics;
+---------------+---------------+------+-----+---------+-------+
| Field         | Type          | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+-------+
| TABLE_CATALOG | varchar(512)  | NO   |     |         |       |
| TABLE_SCHEMA  | varchar(64)   | NO   |     |         |       |
| TABLE_NAME    | varchar(64)   | NO   |     |         |       |
| NON_UNIQUE    | bigint(1)     | NO   |     | 0       |       |
| INDEX_SCHEMA  | varchar(64)   | NO   |     |         |       |
| INDEX_NAME    | varchar(64)   | NO   |     |         |       |
| SEQ_IN_INDEX  | bigint(2)     | NO   |     | 0       |       |
| COLUMN_NAME   | varchar(64)   | NO   |     |         |       |
| COLLATION     | varchar(1)    | YES  |     | NULL    |       |
| CARDINALITY   | bigint(21)    | YES  |     | NULL    |       |
| SUB_PART      | bigint(3)     | YES  |     | NULL    |       |
| PACKED        | varchar(10)   | YES  |     | NULL    |       |
| NULLABLE      | varchar(3)    | NO   |     |         |       |
| INDEX_TYPE    | varchar(16)   | NO   |     |         |       |
| COMMENT       | varchar(16)   | YES  |     | NULL    |       |
| INDEX_COMMENT | varchar(1024) | NO   |     |         |       |
+---------------+---------------+------+-----+---------+-------+
16 rows in set (0.01 sec)

Ви можете обрати цю таблицю за допомогою

SELECT * FROM information_schema.statistics
WHERE table_schema='mydb' AND table_name='mytable';

або переглядати статистику, виконуючи

Показати індекси від mydb.mytable;

Будь ласка, майте на увазі, що ця таблиця не завжди точна у важких умовах. Періодично вам доведеться запускати ANALYZE TABLE проти всіх таблиць MyISAM, які часто оновлюються. В іншому випадку оптимізатор запитів MySQL, який покладається на information_schema.statistics, іноді може робити поганий вибір при розробці планів EXPLAIN для запитів. Статистика індексу повинна бути якомога актуальнішою.

АНАЛІЗНА ТАБЛИЦЯ АБСОЛЮТНО НЕ ЕФЕКТУЄ проти таблиць InnoDB. Вся статистика індексу для InnoDB обчислюється на вимогу за допомогою занурень на сторінки BTREE. Тому, коли ви запускаєте SHOW INDEXES FROM проти InnoDB таблиці, відображені кардинальності завжди є наближеннями.

ОНОВЛЕННЯ 2011-06-21 12:17 EDT

Для уточнення таблиці АНАЛІЗУ дозвольте перефразувати. Запуск таблиці ANALYZE на таблицях InnoDB абсолютно марний. Навіть якщо ви запустили ANALYZE TABLE на таблиці InnoDB, двигун зберігання InnoDB здійснює занурення в індекс для наближення кардіальності знову і знову, тим самим обробляючи статистику, яку ви тільки що склали . Насправді Перкона провів деякі тести на АНАЛІЗОВІЙ СТОЛІ і прийшов до цього висновку також.


5

Re: ТАБЛИКА АНАЛІЗУ АБСОЛЮТНО НЕ ЕФЕКТИВНА щодо таблиць InnoDB.

Я не впевнений, чи це твердження вірно. Ми сильно читаємо та пишемо таблиці innodb, і коли оптимізатор mysql робить поганий вибір, вихідний запит пояснення показує погану стратегію. а також ПОКАЗНИТИ ІНДЕКСИ з таблиці Innodb показує стільки відмінностей у значеннях їхньої кардинальності. Але запуск команди ANALYZE на цих таблицях innodb виправляє план пояснення, а також забирає дисперсійну поведінку кардинальності. Я не знаю, чи команда таблиці ANALYZE на таблицях Innodb допомагає весь час чи ні, але в нашому випадку це допомогло приблизно 99% часу.

Ми повністю усунули поганий вибір оптимізатора mysql, включивши в наші запити "STRAIGHT_JOIN". Це змусило оптимізатор mysql не робити поганого вибору чи будь-якого вибору, а лише дотримуватися умови JOIN того, що ми визначили в запиті як є.


Я оновив свою відповідь, щоб виділити непотрібність таблиці АНАЛІЗУ в таблицях InnoDB.
RolandoMySQLDBA

Я погоджуюся з вашою відповіддю, коли ви згадали про розбіжність у кардинальності. Саме це я і говорив, коли говорив про наближення кардинальності.
RolandoMySQLDBA

Мені також потрібно було зазначити, що використання підказів у запитах - це не завжди найкраще, що робити, коли оптимізатор запитів MySQL прагне їх усунути часом. Ось посилання на те, що відбувається всередині запитів, які можуть фактично змусити дані зникати в частинах планів запитів: dba.stackexchange.com/questions/1371/…
RolandoMySQLDBA

2

ТАБЛИКА АНАЛІЗУ для MyISAM сканує всю таблицю і відновлює статистику, яка зберігається у (я думаю) файлі .MYI. Він потрібен рідко.

ТАБЛИЦЯ АНАЛІЗУ для InnoDB робить щось - це занурення. Проблема полягає в тому, що це може допомогти, може погіршити ситуацію або (швидше за все) не змінити видимих ​​змін (за винятком кардинальності).

Новіші версії обіцяють дозволити змінити 8 не так-то випадкових зондів на (1) більш випадкові, (2) дозволяти вам змінити "8" (є плюси і мінуси цього!) І (3) заощадити під час перезапуску.

Підсумок: InnoDB досі не зрозумів це "правильно". Зробіть АНАЛІЗ, коли вам це подобається, але не затримуйте дихання.

Оновлення

Переформулювання фрази ... ANALYZE TABLEмає тимчасовий вплив (можливо, корисний, можливо, не) на оптимізацію таблиць InnoDB.

"Більш нова версія": Починаючи з 5.6.6 (2012) та MariaDB 10.1 (2014), статистика обробляється набагато краще, а ANALYZEзараз (1) рідше потрібна та (2) більш постійна.

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