Spec-Zone.ru › MySQL 9.2

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;

Информация о том, является ли индекс видимым или невидимым, доступна из таблицы Справочной схемы 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-9.2-en/invisible-indexes.html

Spec-Zone.ru

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