Откуда MySQL Query Optimizer читает статистику индекса?

14

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

ivotron
источник
+1 за этот хороший вопрос, потому что разработчики и администраторы баз данных должны остановиться и подумать о том, как статистика индекса собирается и хранится.
RolandoMySQLDBA
Для справки, на веб-сайте документации mysql: < dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html >> ANALYZE TABLEопределяет количество элементов индекса (как показано в SHOW INDEXвыходных данных столбца Cardinality ), выполняя восемь случайных погружений для каждого деревьев индексов и обновляет оценки индекса мощности соответственно. Поскольку это только оценки, повторные прогоны таблицы ANALYZE могут давать разные числа. Это ANALYZE TABLEускоряет работу с таблицами InnoDB, но не дает 100% точности, поскольку не учитывает все строки.
Чэнь Се,

Ответы:

6

Прямой ответ на это будет

information_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 Query Optimizer, который опирается на information_schema.statistics, иногда может сделать неправильный выбор при разработке планов EXPLAIN для запросов. Статистика индекса должна быть как можно более актуальной.

ANALYZE TABLE АБСОЛЮТНО НЕТ ЭФФЕКТА против таблиц InnoDB. Вся индексная статистика для InnoDB вычисляется по требованию посредством погружений на страницы BTREE. Поэтому, когда вы запускаете SHOW INDEXES FROM для таблицы InnoDB, отображаемое количество элементов всегда является приблизительным.

ОБНОВЛЕНИЕ 2011-06-21 12:17 ПО ВОСТОЧНОМУ ВРЕМЕНИ

Для разъяснения таблицы АНАЛИЗ, позвольте мне перефразировать. Запуск ANALYZE TABLE для таблиц InnoDB совершенно бесполезен. Даже если вы запустили ANALYZE TABLE для таблицы InnoDB, механизм хранения InnoDB снова и снова выполняет погружения в индекс для приближений мощности, таким образом уничтожая только что скомпилированную статистику . Фактически, Percona провела несколько тестов на ANALYZE TABLE и также пришла к этому выводу.

RolandoMySQLDBA
источник
5

Re: ANALYZE TABLE АБСОЛЮТНО НЕТ ЭФФЕКТА против таблиц InnoDB.

Я не уверен, верно ли это утверждение. Мы много читаем и пишем таблицы innodb, и когда оптимизатор mysql делает неправильный выбор, вывод объяснения запроса показывает плохую стратегию. а также ШОУ-ИНДЕКСЫ из таблицы Innodb показывают, что их значения кардинальности сильно отличаются. Но выполнение команды ANALYZE для этих таблиц innodb исправляет план объяснения, а также устраняет дисперсионное поведение кардинальности. Я не знаю, помогает ли команда ANALYZE table на таблицах Innodb постоянно или нет, но в нашем случае она помогала примерно в 99% случаев.

Мы полностью устранили неудачный выбор оптимизатора mysql, добавив в наши запросы «STRAIGHT_JOIN». Это заставило оптимизатор mysql не делать неправильных или каких-либо выборов, а просто следовать условию JOIN того, что мы определили в запросе как есть.

Revathi
источник
Я обновил свой ответ, чтобы подчеркнуть бесполезность ANALYZE TABLE для таблиц InnoDB.
RolandoMySQLDBA
Я согласен с вашим ответом, когда вы упомянули разницу в кардинальности. Это именно то, что я говорил, когда говорил приближения кардинальности.
RolandoMySQLDBA
Я также должен был упомянуть, что использование подсказок в запросах не всегда является наилучшим вариантом, когда MySQL Query Optimizer иногда их устраняет. Вот ссылка на то, что происходит внутри с запросами, которые могут фактически привести к исчезновению данных в частях планов запросов: dba.stackexchange.com/questions/1371/…
RolandoMySQLDBA
2

ANALYZE TABLE for MyISAM сканирует всю таблицу и перестраивает статистику, которая сохраняется (я думаю) в файле .MYI. Это редко нужно.

ANALYZE TABLE для InnoDB делает что - то сделать - это делает погружение упоминается. Проблема в том, что это может помочь, может ухудшить ситуацию или (скорее всего) не окажет заметного влияния (за исключением количества элементов).

Более новые версии обещают разрешить замену 8 неслучайных проб на (1) более случайную, (2) позволить вам изменить «8» (есть плюсы и минусы этого!) И (3) сохранение при перезапусках.

Итог: InnoDB до сих пор не понял «правильно». Проанализируйте, когда вам это нравится, но не задерживайте дыхание.

Обновить

Перефразировка ... ANALYZE TABLEоказывает временное влияние (возможно, полезное, а может и нет) на оптимизацию таблиц InnoDB.

«Более новая версия»: Начиная с 5.6.6 (2012) и MariaDB 10.1 (2014), статистика обрабатывается намного лучше, и ANALYZEтеперь (1) реже требуется и (2) более постоянна.

Рик Джеймс
источник