Spec-Zone.ru › MySQL 8.4

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.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/invisible-indexes.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API