14.8.11.1 Настройка параметров постоянных статистических данных оптимизатора
- 14.8.11.1.1 Настройка автоматического расчета статистики для постоянных статистических данных оптимизатора
- 14.8.11.1.2 Настройка параметров статистики оптимизатора для отдельных таблиц
- 14.8.11.1.3 Настройка количества выборочных страниц для статистики оптимизатора InnoDB
- 14.8.11.1.4 Включение удаленных записей в расчет постоянной статистики
- 14.8.11.1.5 Таблицы постоянной статистики InnoDB
- 14.8.11.1.6 Пример таблиц постоянной статистики InnoDB
- 14.8.11.1.7 Получение размера индекса с помощью таблицы innodb_index_stats
Функция постоянной статистики оптимизатора улучшает производительность, сохраняя статистику на диск и делая ее постоянной при перезапуске сервера, что повышает вероятность того, что будет принимать согласованные решения каждый раз для заданного запроса.
Статистика оптимизатора сохраняется на диск, когда innodb_stats_persistent=ON или когда отдельные таблицы определяются с помощью STATS_PERSISTENT=1. innodb_stats_persistent включен по умолчанию.
Ранее статистика оптимизатора очищалась при перезапуске сервера и после некоторых других типов операций, и пересчитывалась при следующем доступе к таблице. В результате при перерасчете статистики могли быть получены разные оценки, что приводило к разным решениям в планах выполнения запросов и вариациям производительности запросов.
Постоянная статистика хранится в таблицах mysql.innodb_table_stats и mysql.innodb_index_stats. См. Раздел 14.8.11.1.5, «Таблицы постоянной статистики InnoDB».
Если вы предпочитаете не сохранять статистику оптимизатора на диск, см. Раздел 14.8.11.2, «Настройка параметров статистики оптимизатора без сохранения на диск»
14.8.11.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.
14.8.11.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;
14.8.11.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. Количество столбцов в первичном ключе таблицы также важно учитывать, так как столбцы первичного ключа добавляются к каждому не уникальному индексу.Дополнительная информация приведена в Разделе 14.8.11.3, «Оценивание сложности ANALYZE TABLE для таблиц InnoDB».
14.8.11.1.4 Включение строк, помеченных как удаленные, в вычисления постоянной статистики
По умолчанию, InnoDB считывает данные, не подтверждённые, при расчёте статистики. В случае незавершенной транзакции, удаляющей строки из таблицы, строки, помеченные на удаление, исключаются при вычислении оценок строк и статистики индексов, что может привести к не оптимальным планам выполнения для других транзакций, работающих с таблицей одновременно с уровнем изоляции транзакции, отличным от READ UNCOMMITTED. Чтобы избежать этой ситуации, можно включить параметр innodb_stats_include_delete_marked для включения строк, помеченных на удаление, при расчёте постоянной статистики оптимизатора.
При включенном innodb_stats_include_delete_marked, ANALYZE TABLE учитывает строки, помеченные на удаление, при перерасчёте статистики.
innodb_stats_include_delete_marked - это глобальное значение, которое влияет на все InnoDB таблицы, и оно применимо только к постоянной статистике оптимизатора.
innodb_stats_include_delete_marked была введена в MySQL 5.7.16.
14.8.11.1.5 Таблицы постоянной статистики InnoDB
Функция постоянной статистики использует управляемые изнутри таблицы в базе данных mysql, называемые innodb_table_stats и innodb_index_stats. Эти таблицы создаются автоматически во всех процедурах установки, обновления и сборки из исходного кода.
Таблица 14.4 Столбцы таблицы innodb_table_stats
| Имя столбца | Описание |
|---|---|
database_name | Имя базы данных |
table_name | Имя таблицы, имя раздела или имя подраздела |
last_update | Отметка времени, указывающая последний раз, когда строка была обновлена |
n_rows | Количество строк в таблице |
clustered_index_size | Размер первичного индекса в страницах |
sum_of_other_index_sizes | Общий размер других (не первичных) индексов в страницах |
Таблица 14.5 Столбцы таблицы innodb_index_stats
| Имя столбца | Описание |
|---|---|
database_name | Имя базы данных |
table_name | Имя таблицы, имя раздела или имя подраздела |
index_name | Имя индекса |
last_update | Отметка времени, указывающая последний раз, когда InnoDB обновил эту строку |
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 для инициирования синхронного перерасчёта статистики, этот оператор реплицируется (если вы не отключили для него логирование), и перерасчёт выполняется на репликах.
14.8.11.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набора результатов.
14.8.11.1.7 Получение размера индекса с помощью таблицы innodb_index_stats
Вы можете получить размер индекса для таблиц, разделов или подразделов, используя таблицу innodb_index_stats. В приведенном ниже примере размеры индексов извлекаются для таблицы t1. Для определения таблицы t1 и соответствующей статистики индекса см. Раздел 14.8.11.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.