Ignored Indexes
MariaDB starting with 10.6.0
Ignored indexes were added in MariaDB 10.6.
Ignored indexes are indexes that are visible and maintained, but which are not used by the optimizer. MySQL 8 has a similar feature which they call "invisible indexes".
Syntax
By default, an index is not ignored. One can mark existing index as ignored (or not ignored) with an ALTER TABLE statement:
ALTER TABLE table_name ALTER {KEY|INDEX} [IF EXISTS] key_name [NOT] IGNORED;
It is also possible to specify IGNORED attribute when creating an index with a CREATE TABLE, or CREATE INDEX statement:
CREATE TABLE table_name ( ... INDEX index_name ( ...) [NOT] IGNORED ...
CREATE INDEX index_name (...) [NOT] IGNORED ON tbl_name (...);
table's primary key cannot be ignored. This applies to both explicitly defined primary key, as well as implicit primary key - if there is no explicit primary key defined but the table has a unique key containing only NOT NULL columns, the first of such keys becomes the implicitly defined primary key.
Handling for ignored indexes
The optimizer will treats ignored indexes as if they didn't exist. They will not be used in the query plans, or as a source of statistical information.
Also, an attempt to use an ignored index in a USE INDEX
, FORCE INDEX
, or IGNORE INDEX
hint will result in an error - the same what would have if one used a name of a non-existent index.
Information about whether or not indexes are ignored can be viewed in the IGNORED column in the Information Schema STATISTICS table or the SHOW INDEX statement.
Intended Usage
The primary use case is as follows: a DBA sees an index that seems to have little or no usage and considers whether to remove it. Dropping the index is a risk as it may still be needed in a few cases. For example, the optimizer may rely on the estimates provided by the index without using the index in query plans. If dropping an index causes an issue, it will take a while to re-create the index. On the other hand, marking the index as ignored (or not ignored) is instant, so the suggested workflow is:
- Mark the index as ignored
- Check if everything continues to work
- If not, mark the index as not ignored.
- If everything continues to work, one can safely drop the index.
Examples
CREATE TABLE t1 (id INT PRIMARY KEY, b INT, KEY k1(b) IGNORED);
CREATE OR REPLACE TABLE t1 (id INT PRIMARY KEY, b INT, KEY k1(b)); ALTER TABLE t1 ALTER INDEX k1 IGNORED;
CREATE OR REPLACE TABLE t1 (id INT PRIMARY KEY, b INT); CREATE INDEX k1 ON t1(b) IGNORED;
SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'\G *************************** 1. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: test TABLE_NAME: t1 NON_UNIQUE: 0 INDEX_SCHEMA: test INDEX_NAME: PRIMARY SEQ_IN_INDEX: 1 COLUMN_NAME: id COLLATION: A CARDINALITY: 0 SUB_PART: NULL PACKED: NULL NULLABLE: INDEX_TYPE: BTREE COMMENT: INDEX_COMMENT: IGNORED: NO *************************** 2. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: test TABLE_NAME: t1 NON_UNIQUE: 1 INDEX_SCHEMA: test INDEX_NAME: k1 SEQ_IN_INDEX: 1 COLUMN_NAME: b COLLATION: A CARDINALITY: 0 SUB_PART: NULL PACKED: NULL NULLABLE: YES INDEX_TYPE: BTREE COMMENT: INDEX_COMMENT: IGNORED: YES
SHOW INDEXES FROM t1\G *************************** 1. row *************************** Table: t1 Non_unique: 0 Key_name: PRIMARY Seq_in_index: 1 Column_name: id Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: Index_type: BTREE Comment: Index_comment: Ignored: NO *************************** 2. row *************************** Table: t1 Non_unique: 1 Key_name: k1 Seq_in_index: 1 Column_name: b Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: Ignored: YES
The optimizer does not make use of an index when it is ignored, while if the index is not ignored (the default), the optimizer will consider it in the optimizer plan, as shown in the EXPLAIN output.
CREATE OR REPLACE TABLE t1 (id INT PRIMARY KEY, b INT, KEY k1(b) IGNORED); EXPLAIN SELECT * FROM t1 ORDER BY b; +------+-------------+-------+------+---------------+------+---------+------+------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+-------+------+---------------+------+---------+------+------+----------------+ | 1 | SIMPLE | t1 | ALL | NULL | NULL | NULL | NULL | 1 | Using filesort | +------+-------------+-------+------+---------------+------+---------+------+------+----------------+ ALTER TABLE t1 ALTER INDEX k1 NOT IGNORED; EXPLAIN SELECT * FROM t1 ORDER BY b; +------+-------------+-------+-------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+-------+-------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | t1 | index | NULL | k1 | 5 | NULL | 1 | Using index | +------+-------------+-------+-------+---------------+------+---------+------+------+-------------+