17.8.10.1 Настройка параметров постоянных статистических данных оптимизатора
- 17.8.10.1.1 Настройка автоматического расчета статистики для постоянных статистических данных оптимизатора
- 17.8.10.1.2 Настройка параметров статистики оптимизатора для отдельных таблиц
- 17.8.10.1.3 Настройка количества выборочных страниц для статистики оптимизатора InnoDB
- 17.8.10.1.4 Включение строк, помеченных на удаление, в расчеты постоянной статистики
- 17.8.10.1.5 Таблицы постоянной статистики InnoDB
- 17.8.10.1.6 Пример таблиц постоянной статистики InnoDB
- 17.8.10.1.7 Получение размера индекса с помощью таблицы innodb_index_stats
Функция постоянной статистики оптимизатора улучшает производительность, сохраняя статистику на диске и делая ее постоянной между перезапусками сервера, так что оптимизатор с большей вероятностью будет принимать последовательные решения каждый раз для данного запроса.
Статистические данные оптимизатора сохраняются на диске, когда innodb_stats_persistent=ON или когда отдельные таблицы определены с STATS_PERSISTENT=1. innodb_stats_persistent включен по умолчанию.
Ранее статистические данные оптимизатора очищались при перезапуске сервера и после некоторых других операций и пересчитывались при следующем обращении к таблице. В результате при пересчете статистики могли генерироваться различные оценки, что приводило к различным выборам планов выполнения запросов и различиям в производительности запросов.
Постоянная статистика хранится в таблицах mysql.innodb_table_stats и mysql.innodb_index_stats. См. Раздел 17.8.10.1.5, «Таблицы постоянной статистики InnoDB».
Если вы предпочитаете не сохранять статистические данные оптимизатора на диске, см. Раздел 17.8.10.2, «Настройка параметров статистики оптимизатора без сохранения»
17.8.10.1.1 Настройка автоматического расчета статистики для постоянных статистических данных оптимизатора
Переменная innodb_stats_auto_recalc, которая включена по умолчанию, управляет тем, рассчитываются ли статистические данные автоматически, когда таблица претерпевает изменения более чем в 10% своих строк. Вы также можете настроить автоматический перерасчет статистики для отдельных таблиц, указав предложение STATS_AUTO_RECALC при создании или изменении таблицы.
Из-за асинхронного характера автоматического перерасчета статистики, который выполняется в фоновом режиме, статистика может не пересчитываться немедленно после выполнения операции DML, затрагивающей более 10% таблицы, даже когда innodb_stats_auto_recalc включено. Перерасчет статистики может задерживаться на несколько секунд в некоторых случаях. Если актуальные статистические данные требуются немедленно, выполните ANALYZE TABLE для инициирования синхронного (фонового) перерасчета статистики.
Если innodb_stats_auto_recalc отключено, вы можете обеспечить точность статистических данных оптимизатора, выполнив оператор ANALYZE
TABLE после внесения существенных изменений в индексированные столбцы. Вы также можете добавить ANALYZE TABLE в скрипты настройки, которые вы запускаете после загрузки данных, и запустить ANALYZE TABLE в графике в периоды низкой активности.
При добавлении индекса в существующую таблицу или добавлении или удалении столбца статистические данные индекса рассчитываются и добавляются в таблицу innodb_index_stats независимо от значения innodb_stats_auto_recalc.
Для гистограммы с AUTO UPDATE включенным (см. Анализ статистики гистограммы), автоматический перерасчет постоянной статистики также приводит к обновлению гистограммы.
17.8.10.1.2 Настройка параметров статистики оптимизатора для отдельных таблиц
innodb_stats_persistent, innodb_stats_auto_recalc и innodb_stats_persistent_sample_pages — это глобальные переменные. Чтобы переопределить эти системные настройки и настроить параметры статистики оптимизатора для отдельных таблиц, можно определить предложения STATS_PERSISTENT, STATS_AUTO_RECALC и STATS_SAMPLE_PAGES в операторах CREATE TABLE или ALTER TABLE.
STATS_PERSISTENTопределяет, следует ли включить для таблицыInnoDB. ЗначениеDEFAULTзаставляет значение настройки постоянной статистики для таблицы определяться настройкойinnodb_stats_persistent. Значение1включает постоянную статистику для таблицы, а значение0отключает функцию. После включения постоянной статистики для отдельной таблицы, используйтеANALYZE TABLEдля расчета статистики после загрузки данных в таблицу.STATS_AUTO_RECALCопределяет, следует ли автоматически пересчитывать . ЗначениеDEFAULTзаставляет настройку постоянной статистики для таблицы определяться настройкойinnodb_stats_auto_recalc. Значение1заставляет статистику пересчитываться, когда 10% данных таблицы изменились. Значение0предотвращает автоматический перерасчет для таблицы. При использовании значения 0 используйтеANALYZE TABLEдля перерасчета статистики после внесения существенных изменений в таблицу.STATS_SAMPLE_PAGESопределяет количество страниц индекса для выборки при расчете кардинальности и других статистических данных для индексированного столбца, например, при операцииANALYZE TABLE.
Все три предложения указаны в следующем примере CREATE TABLE:
CREATE TABLE `t1` (
`id` int(8) NOT NULL auto_increment,
`data` varchar(255),
`date` datetime,
PRIMARY KEY (`id`),
INDEX `DATE_IX` (`date`)
) ENGINE=InnoDB,
STATS_PERSISTENT=1,
STATS_AUTO_RECALC=1,
STATS_SAMPLE_PAGES=25;
17.8.10.1.3 Настройка количества выборочных страниц для статистики оптимизатора InnoDB
Оптимизатор использует оценки распределения ключей для выбора индексов в плане выполнения, основываясь на относительной важности индекса. Такие операции, как ANALYZE
TABLE, вызывают InnoDB выборку случайных страниц из каждого индекса таблицы для оценки важности индекса. Этот метод выборки известен как .
Параметр innodb_stats_persistent_sample_pages управляет количеством выборочных страниц. Вы можете настроить это значение во время выполнения для управления качеством оценок статистики, используемых оптимизатором. Значение по умолчанию составляет 20. Рассмотрите возможность изменения значения при возникновении следующих проблем:
-
Статистика недостаточно точна, и оптимизатор выбирает не оптимальные планы, как показано в выводе
EXPLAIN. Вы можете проверить точность статистики, сравнив фактическую мощность индекса (определённую путём выполненияSELECT DISTINCTпо столбцам индекса) с оценками в таблицеmysql.innodb_index_stats.Если выяснится, что статистика недостаточно точна, значение
innodb_stats_persistent_sample_pagesследует увеличить до достижения достаточной точности оценок статистики. Однако, слишком большое увеличениеinnodb_stats_persistent_sample_pagesможет привести к замедлению выполненияANALYZE TABLE. -
ANALYZE TABLEслишком медленный. В этом случаеinnodb_stats_persistent_sample_pagesследует уменьшить до приемлемого времени выполненияANALYZE TABLE. Однако, слишком большое уменьшение значения может привести к первой проблеме – неточности статистики и не оптимальных планов выполнения запросов.Если баланс между точной статистикой и временем выполнения
ANALYZE TABLEне может быть достигнут, рассмотрите уменьшение количества индексированных столбцов в таблице или ограничение количества партиций для уменьшения сложностиANALYZE TABLE. Также важно учитывать количество столбцов в первичном ключе таблицы, так как столбцы первичного ключа добавляются к каждому не уникальному индексу.Для получения дополнительной информации см. Раздел 17.8.10.3, «Оценивание сложности ANALYZE TABLE для таблиц InnoDB».
17.8.10.1.4 Включение строк, отмеченных как удалённые, в расчёты постоянной статистики
По умолчанию, InnoDB считывает данные, не подтверждённые, при расчете статистики. В случае незавершенной транзакции, удаляющей строки из таблицы, строки, отмеченные как удаленные, исключаются при расчете оценок строк и статистики индекса, что может привести к не оптимальным планам выполнения для других транзакций, работающих с таблицей параллельно с уровнем изоляции транзакции, отличным от READ UNCOMMITTED. Чтобы избежать этой ситуации, можно включить innodb_stats_include_delete_marked для обеспечения включения строк, отмеченных как удаленные, при расчете постоянной статистики оптимизатора.
Когда innodb_stats_include_delete_marked включено, ANALYZE TABLE учитывает строки, отмеченные как удаленные, при перерасчете статистики.
innodb_stats_include_delete_marked — это глобальная настройка, которая влияет на все InnoDB таблицы, и она применима только к постоянной статистике оптимизатора.
17.8.10.1.5 Таблицы постоянной статистики InnoDB
Функция постоянной статистики использует внутренние управляемые таблицы в базе данных mysql, названные innodb_table_stats и innodb_index_stats. Эти таблицы автоматически создаются во всех процедурах установки, обновления и сборки из исходного кода.
Таблица 17.6 Столбцы таблицы innodb_table_stats
| Имя столбца | Описание |
|---|---|
database_name | Имя базы данных |
table_name | Имя таблицы, раздела или подраздела |
last_update | Отметка времени, показывающая последний раз, когда InnoDB обновила эту строку |
n_rows | Количество строк в таблице |
clustered_index_size | Размер первичного индекса в страницах |
sum_of_other_index_sizes | Общий размер других индексов (не первичный) в страницах |
Таблица 17.7 Столбцы таблицы innodb_index_stats
| Имя столбца | Описание |
|---|---|
database_name | Имя базы данных |
table_name | Имя таблицы, раздела или подраздела |
index_name | Имя индекса |
last_update | Отметка времени, показывающая последний раз, когда строка была обновлена |
stat_name | Имя статистики, значение которой отображается в столбце stat_value |
stat_value | Значение статистики, имя которой указано в столбце stat_name |
sample_size | Количество страниц, выборочно взятых для оценки, предоставленной в столбце stat_value |
stat_description | Описание статистики, имя которой указано в столбце stat_name |
Таблицы innodb_table_stats и innodb_index_stats содержат столбец last_update, который показывает, когда статистика индекса была обновлена последним раз:
mysql> SELECT * FROM innodb_table_stats \G
*************************** 1. row ***************************
database_name: sakila
table_name: actor
last_update: 2014-05-28 16:16:44
n_rows: 200
clustered_index_size: 1
sum_of_other_index_sizes: 1
...mysql> SELECT * FROM innodb_index_stats \G
*************************** 1. row ***************************
database_name: sakila
table_name: actor
index_name: PRIMARY
last_update: 2014-05-28 16:16:44
stat_name: n_diff_pfx01
stat_value: 200
sample_size: 1
...Таблицы innodb_table_stats и innodb_index_stats можно обновлять вручную, что позволяет принудительно использовать определенный план оптимизации запросов или проверять альтернативные планы без изменения базы данных. Если вы вручную обновляете статистику, используйте оператор FLUSH TABLE
для загрузки обновленной статистики.tbl_name
Постоянная статистика считается локальной информацией, так как она относится к экземпляру сервера. Таблицы innodb_table_stats и innodb_index_stats поэтому не реплицируются при автоматическом перерасчете статистики. Если вы запустите ANALYZE TABLE для инициирования синхронного перерасчета статистики, оператор будет реплицирован (если вы не запретили журналирование для него), и перерасчет произойдет на репликах.
17.8.10.1.6 Пример таблиц постоянной статистики InnoDB
Таблица innodb_table_stats содержит одну строку для каждой таблицы. В следующем примере показан тип собираемых данных.
Таблица t1 содержит первичный индекс (столбцы a, b), вторичный индекс (столбцы c, d) и уникальный индекс (столбцы e,
f):
CREATE TABLE t1 (
a INT, b INT, c INT, d INT, e INT, f INT,
PRIMARY KEY (a, b), KEY i1 (c, d), UNIQUE KEY i2uniq (e, f)
) ENGINE=INNODB;
После вставки пяти строк тестовых данных таблица t1 выглядит следующим образом:
mysql> SELECT * FROM t1;
+---+---+------+------+------+------+
| a | b | c | d | e | f |
+---+---+------+------+------+------+
| 1 | 1 | 10 | 11 | 100 | 101 |
| 1 | 2 | 10 | 11 | 200 | 102 |
| 1 | 3 | 10 | 11 | 100 | 103 |
| 1 | 4 | 10 | 12 | 200 | 104 |
| 1 | 5 | 10 | 12 | 100 | 105 |
+---+---+------+------+------+------+
Чтобы немедленно обновить статистику, запустите ANALYZE TABLE (если innodb_stats_auto_recalc включен, статистика обновляется автоматически в течение нескольких секунд, при условии, что достигнут пороговый уровень в 10% измененных строк таблицы):
mysql> ANALYZE TABLE t1;
+---------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+---------+---------+----------+----------+
| test.t1 | analyze | status | OK |
+---------+---------+----------+----------+
Статистика таблицы для таблицы t1 показывает, когда в последний раз InnoDB обновил статистику таблицы (2014-03-14 14:36:34), количество строк в таблице (5), размер кластерного индекса (1 страница) и объединенный размер других индексов (2 страниц).
mysql> SELECT * FROM mysql.innodb_table_stats WHERE table_name like 't1'\G
*************************** 1. row ***************************
database_name: test
table_name: t1
last_update: 2014-03-14 14:36:34
n_rows: 5
clustered_index_size: 1
sum_of_other_index_sizes: 2
Таблица innodb_index_stats содержит несколько строк для каждого индекса. Каждая строка в таблице innodb_index_stats предоставляет данные, относящиеся к определенной статистике индекса, которая указана в столбце stat_name и описана в столбце stat_description. Например:
mysql> SELECT index_name, stat_name, stat_value, stat_description
FROM mysql.innodb_index_stats WHERE table_name like 't1';
+------------+--------------+------------+-----------------------------------+
| index_name | stat_name | stat_value | stat_description |
+------------+--------------+------------+-----------------------------------+
| PRIMARY | n_diff_pfx01 | 1 | a |
| PRIMARY | n_diff_pfx02 | 5 | a,b |
| PRIMARY | n_leaf_pages | 1 | Number of leaf pages in the index |
| PRIMARY | size | 1 | Number of pages in the index |
| i1 | n_diff_pfx01 | 1 | c |
| i1 | n_diff_pfx02 | 2 | c,d |
| i1 | n_diff_pfx03 | 2 | c,d,a |
| i1 | n_diff_pfx04 | 5 | c,d,a,b |
| i1 | n_leaf_pages | 1 | Number of leaf pages in the index |
| i1 | size | 1 | Number of pages in the index |
| i2uniq | n_diff_pfx01 | 2 | e |
| i2uniq | n_diff_pfx02 | 5 | e,f |
| i2uniq | n_leaf_pages | 1 | Number of leaf pages in the index |
| i2uniq | size | 1 | Number of pages in the index |
+------------+--------------+------------+-----------------------------------+
Столбец stat_name показывает следующие типы статистики:
size: Гдеstat_name=size, столбецstat_valueотображает общее количество страниц в индексе.n_leaf_pages: Гдеstat_name=n_leaf_pages, столбецstat_valueотображает количество листовых страниц в индексе.n_diff_pfx: ГдеNNstat_name=n_diff_pfx01, столбецstat_valueотображает количество различных значений в первом столбце индекса. Гдеstat_name=n_diff_pfx02, столбецstat_valueотображает количество различных значений в первых двух столбцах индекса и так далее. Гдеstat_name=n_diff_pfx, столбецNNstat_descriptionпоказывает список столбцов индекса, которые учитываются, разделенный запятыми.
Для дальнейшей иллюстрации статистики n_diff_pfx, которая предоставляет данные о мощности множества, рассмотрим еще раз пример таблицы NNt1, который был представлен ранее. Как показано ниже, таблица t1 создается с первичным индексом (столбцы a, b), вторичным индексом (столбцы c, d) и уникальным индексом (столбцы e, f):
CREATE TABLE t1 (
a INT, b INT, c INT, d INT, e INT, f INT,
PRIMARY KEY (a, b), KEY i1 (c, d), UNIQUE KEY i2uniq (e, f)
) ENGINE=INNODB;
После вставки пяти строк тестовых данных таблица t1 выглядит следующим образом:
mysql> SELECT * FROM t1;
+---+---+------+------+------+------+
| a | b | c | d | e | f |
+---+---+------+------+------+------+
| 1 | 1 | 10 | 11 | 100 | 101 |
| 1 | 2 | 10 | 11 | 200 | 102 |
| 1 | 3 | 10 | 11 | 100 | 103 |
| 1 | 4 | 10 | 12 | 200 | 104 |
| 1 | 5 | 10 | 12 | 100 | 105 |
+---+---+------+------+------+------+
При запросе к index_name, stat_name, stat_value и stat_description, где stat_name LIKE 'n_diff%', возвращается следующий результирующий набор:
mysql> SELECT index_name, stat_name, stat_value, stat_description
FROM mysql.innodb_index_stats
WHERE table_name like 't1' AND stat_name LIKE 'n_diff%';
+------------+--------------+------------+------------------+
| index_name | stat_name | stat_value | stat_description |
+------------+--------------+------------+------------------+
| PRIMARY | n_diff_pfx01 | 1 | a |
| PRIMARY | n_diff_pfx02 | 5 | a,b |
| i1 | n_diff_pfx01 | 1 | c |
| i1 | n_diff_pfx02 | 2 | c,d |
| i1 | n_diff_pfx03 | 2 | c,d,a |
| i1 | n_diff_pfx04 | 5 | c,d,a,b |
| i2uniq | n_diff_pfx01 | 2 | e |
| i2uniq | n_diff_pfx02 | 5 | e,f |
+------------+--------------+------------+------------------+
Для индекса PRIMARY есть две строки n_diff%. Количество строк равно количеству столбцов в индексе.
Для не уникальных индексов InnoDB добавляет столбцы первичного ключа.
Где
index_name=PRIMARYиstat_name=n_diff_pfx01,stat_valueравен1, что указывает на то, что в первом столбце индекса (столбецa) есть одно уникальное значение. Количество уникальных значений в столбцеaподтверждается просмотром данных в столбцеaв таблицеt1, в которой есть одно уникальное значение (1). Подсчитанный столбец (a) показан в столбцеstat_descriptionрезультирующего набора.Где
index_name=PRIMARYиstat_name=n_diff_pfx02,stat_valueравен5, что указывает на то, что в двух столбцах индекса (a,b) есть пять уникальных значений. Количество уникальных значений в столбцахaиbподтверждается просмотром данных в столбцахaиbв таблицеt1, в которой есть пять уникальных значений: (1,1), (1,2), (1,3), (1,4) и (1,5). Подсчитанные столбцы (a,b) показаны в столбцеstat_descriptionрезультирующего набора.
Для вторичного индекса (i1) есть четыре строки n_diff%. Для вторичного индекса определены только два столбца (c,d), но для вторичного индекса есть четыре строки n_diff%, потому что InnoDB добавляет суффикс ко всем не уникальным индексам с первичным ключом. В результате, вместо двух строк есть четыре строки n_diff%, чтобы учесть как столбцы вторичного индекса (c,d), так и столбцы первичного ключа (a,b).
Где
index_name=i1иstat_name=n_diff_pfx01,stat_valueравен1, что указывает на то, что в первом столбце индекса (столбецc) есть одно уникальное значение. Количество уникальных значений в столбцеcподтверждается просмотром данных в столбцеcв таблицеt1, в которой есть одно уникальное значение: (10). Подсчитанный столбец (c) показан в столбцеstat_descriptionрезультирующего набора.Где
index_name=i1иstat_name=n_diff_pfx02,stat_valueравен2, что указывает на то, что в первых двух столбцах индекса (c,d) есть два уникальных значения. Количество уникальных значений в столбцахcиdподтверждается просмотром данных в столбцахcиdв таблицеt1, в которой есть два уникальных значения: (10,11) и (10,12). Подсчитанные столбцы (c,d) показаны в столбцеstat_descriptionрезультирующего набора.Где
index_name=i1иstat_name=n_diff_pfx03,stat_valueравен2, что указывает на то, что в первых трех столбцах индекса (c,d,a) есть два уникальных значения. Количество уникальных значений в столбцахc,dиaподтверждается просмотром данных в столбцахc,dиaв таблицеt1, в которой есть два уникальных значения: (10,11,1) и (10,12,1). Подсчитанные столбцы (c,d,a) показаны в столбцеstat_descriptionрезультирующего набора.Где
index_name=i1иstat_name=n_diff_pfx04,stat_valueравен5, что указывает на то, что в четырех столбцах индекса (c,d,a,b) есть пять уникальных значений. Количество уникальных значений в столбцахc,d,aиbподтверждается просмотром данных в столбцахc,d,aиbв таблицеt1, в которой есть пять уникальных значений: (10,11,1,1), (10,11,1,2), (10,11,1,3), (10,12,1,4) и (10,12,1,5). Подсчитанные столбцы (c,d,a,b) показаны в столбцеstat_descriptionрезультирующего набора.
Для уникального индекса (i2uniq) есть две строки n_diff%.
Где
index_name=i2uniqиstat_name=n_diff_pfx01, значениеstat_valueравно2, что указывает на наличие двух различных значений в первой колонке индекса (колонкаe). Количество различных значений в колонкеeподтверждается просмотром данных в колонкеeв таблицеt1, где есть два различных значения: (100) и (200). Подсчитанная колонка (e) отображается в колонкеstat_descriptionнабора результатов.Где
index_name=i2uniqиstat_name=n_diff_pfx02, значениеstat_valueравно5, что указывает на наличие пяти различных значений в двух колонках индекса (e,f). Количество различных значений в колонкахeиfподтверждается просмотром данных в колонкахeиfв таблицеt1, где есть пять различных значений: (100,101), (200,102), (100,103), (200,104) и (100,105). Подсчитанные колонки (e,f) отображаются в колонкеstat_descriptionнабора результатов.
17.8.10.1.7 Получение размера индекса с помощью таблицы innodb_index_stats
Вы можете получить размер индекса для таблиц, разделов или подразделов, используя таблицу innodb_index_stats. В следующем примере размеры индексов извлекаются для таблицы t1. Определение таблицы t1 и соответствующих статистических данных индекса см. в Разделе 17.8.10.1.6 «Пример таблиц постоянной статистики InnoDB».
mysql> SELECT SUM(stat_value) pages, index_name,
SUM(stat_value)*@@innodb_page_size size
FROM mysql.innodb_index_stats WHERE table_name='t1'
AND stat_name = 'size' GROUP BY index_name;
+-------+------------+-------+
| pages | index_name | size |
+-------+------------+-------+
| 1 | PRIMARY | 16384 |
| 1 | i1 | 16384 |
| 1 | i2uniq | 16384 |
+-------+------------+-------+
Для разделов или подраздёлов вы можете использовать тот же запрос с изменённым фрагментом WHERE, чтобы получить размеры индексов. Например, следующий запрос извлекает размеры индексов для разделов таблицы t1:
mysql> SELECT SUM(stat_value) pages, index_name,
SUM(stat_value)*@@innodb_page_size size
FROM mysql.innodb_index_stats WHERE table_name like 't1#P%'
AND stat_name = 'size' GROUP BY index_name;
© 2025 Oracle
Licensed under the GPLv2 License.