10.3.12 Невидимые индексы
MySQL поддерживает невидимые индексы; то есть индексы, которые не используются оптимизатором. Данная функция применяется к индексам, отличным от первичных ключей (явных или неявных).
По умолчанию индексы видимы. Чтобы явно управлять видимостью нового индекса, используйте ключевое слово VISIBLE или INVISIBLE в определении индекса для CREATE TABLE, CREATE INDEX или ALTER TABLE:
CREATE TABLE t1 (
i INT,
j INT,
k INT,
INDEX i_idx (i) INVISIBLE
) ENGINE = InnoDB;
CREATE INDEX j_idx ON t1 (j) INVISIBLE;
ALTER TABLE t1 ADD INDEX k_idx (k) INVISIBLE;
Чтобы изменить видимость существующего индекса, используйте ключевое слово VISIBLE или INVISIBLE с операцией ALTER TABLE ... ALTER INDEX:
ALTER TABLE t1 ALTER INDEX i_idx INVISIBLE;
ALTER TABLE t1 ALTER INDEX i_idx VISIBLE;
Информация о том, является ли индекс видимым или невидимым, доступна из таблицы Information Schema STATISTICS или результата SHOW INDEX. Например:
mysql> SELECT INDEX_NAME, IS_VISIBLE
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = 'db1' AND TABLE_NAME = 't1';
+------------+------------+
| INDEX_NAME | IS_VISIBLE |
+------------+------------+
| i_idx | YES |
| j_idx | NO |
| k_idx | NO |
+------------+------------+
Невидимые индексы позволяют проверить влияние удаления индекса на производительность запросов без внесения разрушительных изменений, которые необходимо будет отменить, если индекс окажется необходимым. Удаление и повторное добавление индекса может быть дорогостоящим для большой таблицы, тогда как изменение видимости индекса — это быстрые операции на месте.
Если невидимый индекс фактически необходим или используется оптимизатором, существуют несколько способов заметить влияние его отсутствия на запросы к таблице:
Возникают ошибки для запросов, которые включают подсказки индекса, ссылающиеся на невидимый индекс.
Данные Performance Schema показывают увеличение рабочей нагрузки для затронутых запросов.
Запросы имеют разные планы выполнения
EXPLAIN.Запросы появляются в журнале медленных запросов, если они не появлялись там ранее.
Флаг use_invisible_indexes системной переменной optimizer_switch управляет тем, использует ли оптимизатор невидимые индексы для построения плана выполнения запроса. Если флаг off (значение по умолчанию), оптимизатор игнорирует невидимые индексы (тот же самый результат, что и до введения этого флага). Если флаг on, невидимые индексы остаются невидимыми, но оптимизатор учитывает их при построении плана выполнения.
Использование подсказки оптимизатора SET_VAR для временного обновления значения optimizer_switch, вы можете включить невидимые индексы только на период одного запроса, как показано ниже:
mysql> EXPLAIN SELECT /*+ SET_VAR(optimizer_switch = 'use_invisible_indexes=on') */
> i, j FROM t1 WHERE j >= 50\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
partitions: NULL
type: range
possible_keys: j_idx
key: j_idx
key_len: 5
ref: NULL
rows: 2
filtered: 100.00
Extra: Using index condition
mysql> EXPLAIN SELECT i, j FROM t1 WHERE j >= 50\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 5
filtered: 33.33
Extra: Using where
Видимость индекса не влияет на его обслуживание. Например, индекс продолжает обновляться при изменениях строк таблицы, а уникальный индекс предотвращает вставку дубликатов в столбец независимо от того, является ли индекс видимым или невидимым.
Таблица без явного первичного ключа может все же иметь эффективный неявный первичный ключ, если у нее есть какие-либо UNIQUE индексы на NOT NULL столбцах. В этом случае первый такой индекс накладывает тот же самый ограничение на строки таблицы, что и явный первичный ключ, и этот индекс нельзя сделать невидимым. Рассмотрим следующее определение таблицы:
CREATE TABLE t2 (
i INT NOT NULL,
j INT NOT NULL,
UNIQUE j_idx (j)
) ENGINE = InnoDB;
Определение не включает явного первичного ключа, но индекс на NOT NULL столбце j накладывает то же самое ограничение на строки, что и первичный ключ, и его нельзя сделать невидимым:
mysql> ALTER TABLE t2 ALTER INDEX j_idx INVISIBLE;
ERROR 3522 (HY000): A primary key index cannot be invisible.
Теперь предположим, что к таблице добавлен явный первичный ключ:
ALTER TABLE t2 ADD PRIMARY KEY (i);
Явный первичный ключ нельзя сделать невидимым. Кроме того, уникальный индекс на j больше не действует как неявный первичный ключ и, как следствие, может быть сделан невидимым:
mysql> ALTER TABLE t2 ALTER INDEX j_idx INVISIBLE;
Query OK, 0 rows affected (0.03 sec)
© 2025 Oracle
Licensed under the GPLv2 License.