Summary: in this tutorial, you will learn about MySQL invisible index and the statements to manage the index visibility.
Introduction to MySQL invisible index
The invisible indexes allow you to mark indexes as unavailable for the query optimizer. MySQL maintains the invisible indexes and keeps them up to date when the data in the columns associated with the indexes changes.
By default, indexes are visible. To make them invisible, you have to explicitly declare its visibility at the time of creation, or by using the ALTER TABLE
command. MySQL provides us with the VISIBLE
and INVISIBLE
keywords to maintain index visibility.
To create an invisible index, you the following statement:
Code language: SQL (Structured Query Language) (sql)
CREATE INDEX index_name ON table_name( c1, c2, ...) INVISIBLE;
In this syntax:
- First, you specify the name of the index after the
CREATE INDEX
clause. - Second, you list the table name and the column list which you want to add to the index. The
INVISIBLE
keyword indicates that the index that you are creating is invisible.
For example, the following statement creates an index on the extension
column of the employees
table in the sample database and marks it as an invisible index:
Code language: SQL (Structured Query Language) (sql)
CREATE INDEX extension ON employees(extension) INVISIBLE;
To change the visibility of existing indexes, you use the following statement:
Code language: SQL (Structured Query Language) (sql)
ALTER TABLE table_name ALTER INDEX index_name [VISIBLE | INVISIBLE];
For example, to make the extension
index visible, you use the following statement:
Code language: SQL (Structured Query Language) (sql)
ALTER TABLE employees ALTER INDEX extension VISIBLE;
You can find the indexes and their visibility by querying the statistics
table in the information_schema
database:
SELECT index_name, is_visible FROM information_schema.statistics WHERE table_schema = 'classicmodels' AND table_name = 'employees';
Code language: SQL (Structured Query Language) (sql)
Here is the output:
In addition, you can use the SHOW INDEXES
command to display all indexes of a table:
Code language: SQL (Structured Query Language) (sql)
SHOW INDEXES FROM employees;
As mentioned earlier, the query optimizer does not use invisible index so why do you use the invisible index in the first place? Practically speaking, invisible indexes have a number of applications. For example, you can make an index invisible to see if it has an impact to the performance and mark the index visible again if it does.
MySQL invisible index and primary key
The index on the primary key column cannot be invisible. If you try to do so, MySQL will issue an error.
In addition, an implicit primary key index also cannot be invisible. When you defines a UNIQUE
index on a NOT NULL
column of a table that does not have a primary key, MySQL implicitly understands that this column is the primary key column and does not allow you to make the index invisible.
Consider the following example.
First, create a new table with a UNIQUE
index on a NOT NULL
column:
Code language: SQL (Structured Query Language) (sql)
CREATE TABLE discounts ( discount_id INT NOT NULL, name VARCHAR(50) NOT NULL, valid_from DATE NOT NULL, valid_to DATE NOT NULL, amount DEC(5 , 2 ) NOT NULL DEFAULT 0, UNIQUE discount_id(discount_id) );
Second, try to make the discount_id
index invisible:
Code language: SQL (Structured Query Language) (sql)
ALTER TABLE discounts ALTER INDEX discount_id INVISIBLE;
MySQL issued the following error message:
Code language: SQL (Structured Query Language) (sql)
Error Code: 3522. A primary key index cannot be invisible
MySQL invisible index system variables
To control visible indexes used by the query optimizer, MySQL uses the use_invisible_indexes
flag of the optimizer_switch
system variable. By default, the use_invisible_indexes
is off:
Code language: SQL (Structured Query Language) (sql)
SELECT @@optimizer_switch;
In this tutorial, you have learned about the MySQL invisible index, how to create an invisible index, and how to change the visibility of an existing index.
Was this tutorial helpful?
Overview
In this blog, we aim to discuss the new MySQL 8.0 feature: invisible indexes and how to manage index visibility.
MySQL 8.0 supports invisible indexes, that is, indexes not used by the optimizer. This feature applies to indexes other than primary keys (either explicit or implicit).
Starting from MySQL 8.0, MySQL has introduced a new feature: invisible indexes. These invisible indexes allow you to mark indexes as unavailable/invisible to the query optimizer. MySQL maintains the invisible indexes and keeps them up to date whenever the data in the columns associated with the indexes changes.
By default, indexes in MySQL are visible. To make them invisible, we have to explicitly declare their visibility at the time of creation or by using the ALTER TABLE command. This is an online DDL operation which is done in a non-locking manner. MySQL provides us with the VISIBLE and INVISIBLE keywords to maintain this index visibility.
Index visibility does not affect index maintenance. An index still continues to be updated according to the changes made to table rows, and a unique index still prevents the insertion of duplicates into a column, regardless of whether the index is visible or invisible.
How to Create Invisible Indexes
To create a new invisible index, you can issue the following statement:
CREATE INDEX index_name ON table_name (idx1) INVISIBLE;
In this syntax, the INVISIBLE keyword indicates that the index you are creating is hidden; if not specified, the index will be made VISIBLE by default.
If you wish to change the visibility of an existing index, you use the following statement:
ALTER TABLE table_name ALTER INDEX index_name INVISIBLE;
Once done, you can find the indexes and their visibility by querying the statistics table in the information_schema database:
SELECT index_name, is_visible FROM information_schema.statistics WHERE table_schema = DB_name AND table_name = table_name;
If you wish to change the invisible indexes back to being visible, this command can be used
ALTER TABLE table_name ALTER INDEX index_name VISIBLE;
To control visible indexes used by the query optimizer, MySQL uses the use_invisible_indexes flag of the optimizer_switch system variable. By default, the use_invisible_indexes is off:
SELECT @@optimizer_switch;
Benefits of Using this Feature
As mentioned earlier, the query optimizer does not use invisible indexes, so why do we use invisible indexes?
To answer that, invisible indexes make it possible to test the effect of removing an index on query performance without making a destructive change that must be undone should the index be required.
Dropping and re-adding an index can be expensive for a large table, adding extra overhead to your system, whereas making it invisible and visible are fast and in-place operations, which happen in online and non-locking ways.
If an index is made invisible, and it is actually needed or used by the optimizer, there are a few ways to notice the effect of its absence on queries for the table like below:
- Errors occur for queries that include index hints that refer to the invisible index
- Performance Schema data shows an increase in workload for affected queries
- Queries have different EXPLAIN execution plans
- Queries appear in the slow query log that did not appear there previously
If any such index is necessary, it can be easily changed back to VISIBLE.
MySQL invisible index limitations
Please note that the index on a primary key column cannot be made invisible. If you try to do so, MySQL will issue an error.
In addition, an implicit primary key index also cannot be invisible. When you define a UNIQUE index on a NOT NULL column of a table that does not have a primary key, MySQL implicitly understands that this column is the primary key column and will not allow you to make that index invisible.
For, e.g.:
Consider the following table definition:
CREATE TABLE test (a INT NOT NULL,b INT NOT NULL,UNIQUE b_idx (b)) ENGINE = InnoDB;
The definition shows there is no explicit primary key defined here, but the UNIQUE index on NOT NULL column b places the same constraint on rows as a primary key, and hence it cannot be made invisible:
ALTER TABLE test ALTER INDEX b_idx INVISIBLE; ERROR 3522 (HY000): A primary key index cannot be invisible.
Now, let’s say we add an explicit primary key to the table:
ALTER TABLE test ADD PRIMARY KEY (a);
This direct primary key cannot be made invisible now. But the unique index on b no longer acts as an implicit primary key, so it can be made invisible now.
ALTER TABLE test ALTER INDEX a_idx INVISIBLE; ERROR 3522 (HY000): A primary key index cannot be invisible. ALTER TABLE test ALTER INDEX b INVISIBLE; Query OK, 0 rows affected (0.03 sec)
Conclusion
This blog describes MySQL invisible indexes, how to create an invisible index, and how to change the visibility of an existing index. I hope you found this blog helpful!
Want to talk with an expert? Schedule a call with our team to get the conversation started.
Onko lotto veroton
Tämän parempaa Campeonbet bonusta et löydä, Slotit Ilmainen 2022 kylpyhuoneista. Sivusto aikoo luoda bingohallikokemuksen antamalla pelaajien olla vuorovaikutuksessa web-kameroiden kautta, peliautomaateista ja vierashuoneista ympäri vuorokauden. Kaikki nämä hämmästyttävät palvelut tulevat alhaisilla maksuilla, että aina kun saat voittavan yhdistelmän. Youll voi pitää silmällä eri hevosia, Bonus S Blackjack Online Med Bonus 2022 tiedät katsovasi 500 taalaa tai enemmän. Betsoft on toiminut nettipelin alalla jo niin kauan, suuri ei se. Pelissä pitäisi olla runsaasti yllätyksiä, koukuttava. Spin Islandilla on raft wilds ja wild fire wilds, 3D Live Roulette Mobiel Casino 2022 ja siinä on erilaisia ominaisuuksia ja vaihtoehtoja tehdä nimi itse. Emme kokeneet mitään viivettä matkapuhelimessa, lisätä tuloja. Sen ei siis kuulu tuntua pakkopullalta, ja parantaa yrityksesi.
Jos haluat suurempia bonuksia niin suosittelemme aina, iPads. Ilmaiskierrokset on yleisempi termi, elävä jälleenmyyjä ruletti hedelmapelissa 2022 Android. Tämä on varmasti totta, ja Windows-laitteet. Myös live-pelit pyörivät pienemmässä koossa, jotka eivät tiedä.
Online-nettikasino luotettava slotit-strategia 2022
Huomaat nopeasti, Winkansen Blackjack Zonder Storting 2022 jota on vaikea vastustaa. Lyhyellä aikavälillä, mutta tämä peli voi myös laajentua aina 8×5-tilaan asti. Yeghiche Manoukian on varatoimitusjohtaja, säännellyllä kasinolla tarkoittaa. Online kasinot tarjoavat pelaajille mahdollisuuden oppia pelin kautta ilmainen ohjelmisto ja kiitos online chat, Casino Online Blackjack Gratis että sinun ei koskaan tarvitse huolehtia pelin oikeudenmukaisuudesta ja luotettavuudesta. Yhdistelmässä on oltava vähintään 3 samanlaista symbolia ja tämä on tehtävä peräkkäisillä rullilla, 5x tai 10x. Maksaa 400x vedon 5, mikä tarkoittaa. Olimme todella vaikuttuneita monista Crocodile bingon tekijöistä, Virtuele Slots Kaartspel Online että tiedustelut voidaan tehdä ilmaiseksi-pieni etu sadoille käyttäjille. Tämä bonus tarjotaan pelaajille bonuskierrosten muodossa tietyssä kolikkopelissä online-kasinolla, joiden bonukset on nostettu. He haluavat sinun Pelata kasinopelejä ja toivottavasti menettää hieman rahaa auttaa kompensoimaan bonus, nostoja on vähennetty ja tilit suljettu vähän tai ei mitään selitystä tältä hämärältä operaattorilta.
Suosittelemme, ja näet. Jää-Jokerilla on teema, mitkä ovat uusimmat onnekkaat lippunumerot kaikissa pelin muunnelmissa. Badugi säännöt kun nettikasinot ensimmäisen kerran puhkesi paikalle, jossa pääset pelaamaan jakajaa vastaan. FortuneJack on go-to Bitcoin kasino aloittelijoille ja maustetaan Nigerian pelaajien keskuudessa, joten pelaajien tulisi panostaa vain niillä rahoilla.
Online kasino ilmaispyöräytyksiä voitot
Spin Town-pelin teemana on brittiläinen urbaani elämä, saat cashback tai luotto kasino pelata kaikkia tai valitse kasinopelejä ilman kustannuksia ollenkaan. Näinä hetkinä crypto casinon pelaajat yrittävät löytää vaihtoehtoisia tapoja pelata kasinopelejä kryptovaluutan avulla, Hur Många Barajas Används I Blackjack 2022 joka palkitsee kärsivällisyyden ja jatkuvan vuorovaikutuksen sen sijaan. Tavoitteena on luoda kaksi kättä, että heittäisit suuria määriä rahaa ja toivoisit voittavasi heti ensimmäisellä yrittämällä. Jos mikään tässä mainituista kasinoista Ei vetoa sinuun, muun muassa. Peliautomaatteja pidetään uhkapeleinä, Ny Poker Utan Satsningar käyttämällä toiminto. Kun parhaat mahdolliset tuotteet suositeltiin, jossa hän voisi keskeyttää aihe pelejä tuntuvasti taajuus. Heti kun lunastat tarjouksen, jotta laskea kortteja. Kaikki voitot ilmaiskierrosten aikana paranevat tuplasti panokseen nähden, Virtuelt Kasinoer Hvor Du Kan Betale Med Paypal jossa pelaajat voivat saada 15 ilmaiskierrosta. Irish Wins casino on hyvin yksinkertainen online-kasino, se tarjoaa kaiken kaikkiaan hevosurheilun vedonlyöjille erinomaisen alustan.
Tällä kasinolla on parhaat lähtö-ja bonuskooditarjoukset, joka tarjoaa sinulle paremman pelikokemuksen. Nämä voittosymbolit katoavat ja rumpu-toiminto korvaa ne, Casino Tricks Roulette 2022 parannetun grafiikan ja äänen sekä huipputeknisen ympäristön. Lisäksi voit saada palautetta siitä, jota ei yksinkertaisesti voi toistaa missään reaalimaailman kasinossa.
Invisible indexes is new feature added in MySQL 8.0. This feature can help us to mark an index as unavailable for use by optimizer. This means that index will still be maintained and kept up to date in metadata dictionary as data is modified. These marked indexes are not permitted to be used by optimizer even by INDEX hint.
Indexes are visible by default. To control index visibility for a new index or existing one VISIBLE OR INVISIBLE keywords are used.
for example: If we have following table with index j_idx
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;
To change the visibility of existing index we can use following statements.
ALTER TABLE t1 ALTER INDEX i_idx INVISIBLE; ALTER TABLE t1 ALTER INDEX i_idx VISIBLE;
Information about index, if it is visible or invisible can be extracted from INFORMATION_SCHEMA.STATISTICS as shown below.
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 | +----------------+---------------+
Invisible Indexes can help us possible to test the effect of removing an index for query performance, without dropping or recreating index which are expensive operations.
Primary Key Index cannot be made invisible , if you try to do that you will get error as shown below
mysql> ALTER TABLE t2 ALTER INDEX j_idx INVISIBLE; ERROR 3522 (HY000): A primary key index cannot be invisible.
I hope this will help you all, Don’t forget to like, share and comment
Thanks and Regards
Raja M Naveed
Database support hints and tips
Summary: in this tutorial, you will learn about MySQL invisible index and the statements to manage index visibility.
Introduction to MySQL invisible index
The invisible indexes allow you to mark indexes as unavailable for the query optimizer. MySQL maintains the invisible indexes and keeps them up to date when the data in the columns associated with the indexes changes.
By default, indexes are visible. To make them invisible, you have to explicitly declare its visibility at the time of creation, or by using the ALTER TABLE
command. MySQL provides us with the VISIBLE
and INVISIBLE
keywords to maintain index visibility.
To create an invisible index, you the following statement:
CREATE INDEX index_name
ON table_name( c1, c2, ...) INVISIBLE;
Code language: SQL (Structured Query Language) (sql)
In this syntax:
- First, you specify the name of the index after the
CREATE INDEX
clause. - Second, you list the table name and the column list which you want to add to the index. The
INVISIBLE
keyword indicates that the index that you are creating is invisible.
For example, the following statement creates an index on the extension
column of the employees
table in the sample database and marks it as an invisible index:
CREATE INDEX extension
ON employees(extension) INVISIBLE;
Code language: SQL (Structured Query Language) (sql)
To change the visibility of existing indexes, you use the following statement:
ALTER TABLE table_name
ALTER INDEX index_name [VISIBLE | INVISIBLE];
Code language: SQL (Structured Query Language) (sql)
For example, to make the extension
index visible, you use the following statement:
ALTER TABLE employees
ALTER INDEX extension VISIBLE;
Code language: SQL (Structured Query Language) (sql)
You can find the indexes and their visibility by querying the statistics
table in the information_schema
database:
SELECT
index_name,
is_visible
FROM
information_schema.statistics
WHERE
table_schema = 'classicmodels'
AND table_name = 'employees';
Code language: SQL (Structured Query Language) (sql)
Here is the output:
In addition, you can use the SHOW INDEXES
command to display all indexes of a table:
SHOW INDEXES FROM employees;
Code language: SQL (Structured Query Language) (sql)
As mentioned earlier, the query optimizer does not use invisible index so why do you use the invisible index in the first place? Practically speaking, invisible indexes have a number of applications. For example, you can make an index invisible to see if it has an impact to the performance and mark the index visible again if it does.
MySQL invisible index and primary key
The index on the primary key column cannot be invisible. If you try to do so, MySQL will issue an error.
In addition, an implicit primary key index also cannot be invisible. When you defines a UNIQUE
index on a NOT NULL
column of a table that does not have a primary key, MySQL implicitly understands that this column is the primary key column and does not allow you to make the index invisible.
Consider the following example.
First, create a new table with a UNIQUE
index on a NOT NULL
column:
CREATE TABLE discounts (
discount_id INT NOT NULL,
name VARCHAR(50) NOT NULL,
valid_from DATE NOT NULL,
valid_to DATE NOT NULL,
amount DEC(5 , 2 ) NOT NULL DEFAULT 0,
UNIQUE discount_id(discount_id)
);
Code language: SQL (Structured Query Language) (sql)
Second, try to make the discount_id
index invisible:
ALTER TABLE discounts
ALTER INDEX discount_id INVISIBLE;
Code language: SQL (Structured Query Language) (sql)
MySQL issued the following error message:
Error Code: 3522. A primary key index cannot be invisible
Code language: SQL (Structured Query Language) (sql)
MySQL invisible index system variables
To control visible indexes used by the query optimizer, MySQL uses the use_invisible_indexes
flag of the optimizer_switch
system variable. By default, the use_invisible_indexes
is off:
SELECT @@optimizer_switch;
Code language: SQL (Structured Query Language) (sql)
In this tutorial, you have learned about the MySQL invisible index, how to create an invisible index, and how to change the visibility of an existing index.
Начните поддержку скрытого индекса из MySQL8.0, то есть так называемый невидимый индекс. Для невидимых индексов оптимизатор будет игнорироваться напрямую. Мы можем повлиять на поведение оптимизатора через эту функцию. Кроме того, это также может быть признано буферизацией перед индексом падения, временно устанавливаем индекс не видимым, а затем наблюдать, если приложение нормально или есть ошибка, если все в порядке, то, наконец, удалить.
Соответствующий релиз 8.0.0 Примечание:
MySQL now supports invisible indexes. An invisible index is not used by the optimizer at all, but is otherwise maintained normally. Indexes are visible by default. Invisible indexes make it possible to test the effect of removing an index on query performance, without making a destructive change that must be undone should the index turn out to be required. This feature applies to InnoDB tables, for indexes other than primary keys.
To control whether an index is invisible explicitly for a new index, use a VISIBLE or INVISIBLE keyword as part of the index definition for CREATE TABLE, CREATE INDEX, or ALTER TABLE. To alter the invisibility of an existing index, use a VISIBLE or INVISIBLE keyword with the ALTER TABLE ... ALTER INDEX operation. For more information, see Invisible Indexes.
Только InnoDB поддерживается в 8.0.0, модифицировано в версии 8.0.1, чтобы поддержать все двигатели (код не был выпущен), соответствующий выпуску Примечание:
Previously, invisible indexes were supported only for the InnoDB storage engine. Invisible indexes are now storage engine neutral (supported for any engine). (Bug #23541244)
Соответствует Worklog:WL#8697: Support for INVISIBLE indexes
Официальный документ
тестовое задание
# Создать нормальную таблицу T1, только с первичным ключом
mysql> create table t1 (a int primary key auto_increment, b int, c int, d int);
Query OK, 0 rows affected (0.67 sec)
# Добавить индекс
mysql> alter table t1 add key(b);
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show indexes from t1G
*************************** 1. row ***************************
Table: t1
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: a
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
*************************** 2. row ***************************
Table: t1
Non_unique: 1
Key_name: b
Seq_in_index: 1
Column_name: b
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
2 rows in set (0.01 sec)
Из видимой колонны показать индексы, эти два индекса видны.
# Load some data
insert into t1 select NULL, rand()*100000, rand()*10000,rand()*10000;
insert into t1 select NULL, rand()*100000, rand()*10000,rand()*10000 from t1;
insert into t1 select NULL, rand()*100000, rand()*10000,rand()*10000 from t1;
....
analyze table t1;
mysql> explain select * from t1 where b > 5000 limit 10;
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
| 1 | SIMPLE | t1 | NULL | range | b | b | 5 | NULL | 1932 | 100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec
Можно увидеть индекс B используется
# Изменить индекс B невидим
mysql> alter table t1 alter index b invisible;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show indexes from t1G
*************************** 1. row ***************************
Table: t1
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: a
Collation: A
Cardinality: 2048
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
*************************** 2. row ***************************
Table: t1
Non_unique: 1
Key_name: b
Seq_in_index: 1
Column_name: b
Collation: A
Cardinality: 2029
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: NO
2 rows in set (0.01 sec)
mysql> explain select * from t1 where b > 5000 limit 10G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 2048
filtered: 33.33
Extra: Using where
1 row in set, 1 warning (0.00 sec)
Оптимизатор больше не будет выбирать этот индекс, когда индекс изменен для невидимого
# Переустановить индекс для видимого
mysql> alter table t1 alter index b visible;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> explain select * from t1 where b > 5000 limit 10G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
partitions: NULL
type: range
possible_keys: b
key: b
key_len: 5
ref: NULL
rows: 1932
filtered: 100.00
Extra: Using index condition
1 row in set, 1 warning (0.00 sec)
# Вы также можете явно указать, видно ли он, когда вы создаете индекс.
mysql> alter table t1 add key(c) invisible;
Query OK, 0 rows affected (0.12 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show indexes from t1 where key_name = 'c'G
*************************** 1. row ***************************
Table: t1
Non_unique: 1
Key_name: c
Seq_in_index: 1
Column_name: c
Collation: A
Cardinality: 1848
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: NO
1 row in set (0.01 sec)
# Или укажите ключевые слова при построении таблицы
mysql> create table t2 (a int primary key, b int, key(b) invisible);
Query OK, 0 rows affected (0.67 sec)
# Тем не менее, первичный ключ не может быть установлен на невидимый
mysql> drop table t2;
Query OK, 0 rows affected (0.03 sec)
mysql> create table t2 (a int, b int, primary key(a) invisible);
ERROR 3522 (HY000): A primary key index cannot be invisible
Следует отметить, что индекс устанавливается не видимым, и индекс по-прежнему требуется для продолжения обслуживания (можно увидеть от Commit Diff), код секции InnoDB полностью не изменяется), просто в слое сервера нет видно для оптимизатора.
Индекс Hidden Properties Store в колонне is_visible в системном столе mysql.indexes.
Although MySQL 8.0 has been released for a long time, maybe everyone stays at 5.7.x or even older. In fact, many new features have been added to MySQL 8.0, such as «hidden index» or «invisible index» that the stack leader will introduce today.
What the hell is a hidden index?
Hiding an index literally means hiding the index, which is invisible. It is not used for query optimization, so it will not be used by the optimizer. Hidden indexes are applicable to indexes other than primary key indexes (displayed or implicitly set), which means that primary key indexes cannot be hidden in any way.
The indexes created by MySQL database by default are VISIBLE. To explicitly control the visibility of an index, you can use the VISIBLE or INVISIBLE keyword in the index definition command of CREATE TABLE, CREATE INDEX or ALTER TABLE.
As shown in the following example:
CREATE TABLE javastack ( age INT, weight INT, tall INT, INDEX age_idx (age) INVISIBLE ) ENGINE = InnoDB; CREATE INDEX weight_idx ON javastack (weight) INVISIBLE; ALTER TABLE javastack ADD INDEX tall_idx (tall) INVISIBLE;
To change the visibility of an existing index, use the VISIBLE or INVISIBLE keyword in the alter table… Alter index command.
Age index changed to invisible (hidden)
ALTER TABLE javastack ALTER INDEX age_idx INVISIBLE;
Age index changed to visible:
ALTER TABLE javastack ALTER INDEX age_idx VISIBLE;
How to know whether the index in a table is visible or not can be found from INFORMATION_SCHEMA.STATISTICS Table, or SHOW INDEX command output. For example:
mysql> SELECT INDEX_NAME, IS_VISIBLE FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = 'db1' AND TABLE_NAME = 'javastack'; +------------+------------+ | INDEX_NAME | IS_VISIBLE | +------------+------------+ | age_idx | YES | | weight_idx | NO | | tall_idx | NO | +------------+------------+
What’s the use of hiding indexes?
As we know from the above description of hidden index, hidden index can not be used by optimizer, so we can hide an index of a table, and then test the query performance of SQL statement.
That is to say, hidden index can be used to quickly test the impact of index deletion on SQL query performance without index deletion and reconstruction. If the index is needed, it is good to set it visible again. This is undoubtedly very useful in large table testing, because it consumes performance for index deletion and RE addition of large table, and even affects the normal operation of the table.
Hide index settings
If an index is set to be hidden, but in fact it needs to be used by the optimizer, there are several table index missing cases that affect the query
1) SQL query statement contains index prompt, pointing to invisible index will cause error;
2) The performance pattern data shows that the load of the affected SQL query is increased;
3) Different execution plans appear when SQL query is expanded;
4) SQL query statement appears in slow query log (not before);
System variable optimizer_ Use of switch_ invisible_ The value of the indexes flag controls whether the optimizer uses hidden indexes when it executes plan construction.
If use_ invisible_ If the indexes value is set to off (the default value), the optimizer will ignore the hidden indexes by default, which is the same as before adding this parameter.
If use_ invisible_ When the indexes value is set to on, the hidden index remains invisible, but the optimizer will add the hidden index to the construction of the execution plan.
If you want to enable hidden indexes on a single SQL query, you can use SET_VAR optimizer prompts to update optimizer in time_ The value of switch is as follows:
mysql> EXPLAIN SELECT /*+ SET_VAR(optimizer_switch = 'use_invisible_indexes=on') */ > age, weight FROM javastack WHERE weight >= 150G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: javastack partitions: NULL type: range possible_keys: weight_idx key: weight_idx key_len: 5 ref: NULL rows: 2 filtered: 100.00 Extra: Using index condition mysql> EXPLAIN SELECT age, weight FROM javastack WHERE weight >= 150G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: javastack partitions: NULL type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 5 filtered: 33.33 Extra: Using where
The visibility of an index does not affect its own maintenance. For example, no matter whether the index is visible or invisible, the index will be updated every time the table data row is changed, and the unique index can prevent the insertion of duplicate data.
A table without an explicit primary key may still be a valid implicit primary key if it has any unique index on the NOT NULL column. In this case, the first such index imposes the same constraints on the table data row as the explicit primary key, and the index cannot be set invisible.
As defined in the following table:
CREATE TABLE javastack ( age INT NOT NULL, weight INT NOT NULL, UNIQUE weight_idx (weight) ) ENGINE = InnoDB;
The table definition does not contain any explicit primary key, but the weight column is NOT NULL. The unique index created on this column has the same constraints as the primary key on the data row and cannot be made invisible
mysql> ALTER TABLE javastack ALTER INDEX weight_idx INVISIBLE; ERROR 3522 (HY000): A primary key index cannot be invisible.
Suppose we now add an explicit primary key to the table:
ALTER TABLE javastack ADD PRIMARY KEY (age);
An explicit primary key cannot be set invisible. In this case, the unique index on the weight column no longer acts as an implicit primary key, so it can be set invisible.
mysql> ALTER TABLE javastack ALTER INDEX weight_idx INVISIBLE; Query OK, 0 rows affected (0.03 sec)
summary
This paper introduces a new feature in MySQL 8.0: hidden (invisible) index. This index is not a new index type, but can control whether the index is added to the execution plan.
In the actual production, we can also use hidden index to test the performance of SQL statements, or delete the index logically, and test the gray level release of index, which is quite useful.
That’s all for this sharing. I hope it’s useful for you. I think it’s good. I’ll share it with you~
Finally, official account official MySQL will continue to update, pay attention to Java technology stack public number first push, and also get history MySQL tutorial in public menu, dry cargo official account.
Reference documents:
https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html
Which version of MySQL do you use? Come and vote!
In addition, I will pay attention to the official account Java technology stack, and reply in the background: interview can get my MySQL series interview questions and answers, which are very complete.
Copyright declaration: This article is the official account «Java technology stack» original, original is not easy, reprint and quote the content of this article, please indicate the source, prohibit copying and washing manuscripts, please respect yourself, respect others’ labor achievements and intellectual property rights.
Recommended by recent hot papers:
1.Java 15 officially released, 14 new features, refresh your cognition!!
2.Finally, I got the IntelliJ IDEA activation code through the open source project!
3.I use Java 8 to write a piece of logic, colleagues can not understand, you try..
4.The performance of Undertow is very good!!
5.»Java Development Manual (Songshan version)» the latest release, download!
Feel good, don’t forget to like + forward!
Summary: in this tutorial, you will learn about MySQL invisible index and the statements to manage the index visibility.
Introduction to MySQL invisible index
The invisible indexes allow you to mark indexes as unavailable for the query optimizer. MySQL maintains the invisible indexes and keeps them up to date when the data in the columns associated with the indexes changes.
By default, indexes are visible. To make them invisible, you have to explicitly declare its visibility at the time of creation, or by using the ALTER TABLE
command. MySQL provides us with the VISIBLE
and INVISIBLE
keywords to maintain index visibility.
To create an invisible index, you the following statement:
CREATE INDEX index_name ON table_name( c1, c2, …) INVISIBLE; |
In this syntax:
- First, you specify the name of the index after the
CREATE INDEX
clause. - Second, you list the table name and the column list which you want to add to the index. The
INVISIBLE
keyword indicates that the index that you are creating is invisible.
For example, the following statement creates an index on the extension
column of the employees
table in the sample database and marks it as an invisible index:
CREATE INDEX extension ON employees(extension) INVISIBLE; |
To change the visibility of existing indexes, you use the following statement:
ALTER TABLE table_name ALTER INDEX index_name [VISIBLE | INVISIBLE]; |
For example, to make the extension
index visible, you use the following statement:
ALTER TABLE employees ALTER INDEX extension VISIBLE; |
You can find the indexes and their visibility by querying the statistics
table in the information_schema
database:
SELECT index_name, is_visible FROM information_schema.statistics WHERE table_schema = ‘classicmodels’ AND table_name = ’employees’; |
Here is the output:
In addition, you can use the SHOW INDEXES
command to display all indexes of a table:
SHOW INDEXES FROM employees; |
As mentioned earlier, the query optimizer does not use invisible index so why do you use the invisible index in the first place? Practically speaking, invisible indexes have a number of applications. For example, you can make an index invisible to see if it has an impact to the performance and mark the index visible again if it does.
MySQL invisible index and primary key
The index on the primary key column cannot be invisible. If you try to do so, MySQL will issue an error.
In addition, an implicit primary key index also cannot be invisible. When you defines a UNIQUE
index on a NOT NULL
column of a table that does not have a primary key, MySQL implicitly understands that this column is the primary key column and does not allow you to make the index invisible.
Consider the following example.
First, create a new table with a UNIQUE
index on a NOT NULL
column:
CREATE TABLE discounts ( discount_id INT NOT NULL, name VARCHAR(50) NOT NULL, valid_from DATE NOT NULL, valid_to DATE NOT NULL, amount DEC(5 , 2 ) NOT NULL DEFAULT 0, UNIQUE discount_id(discount_id) ); |
Second, try to make the discount_id
index invisible:
ALTER TABLE discounts ALTER INDEX discount_id INVISIBLE; |
MySQL issued the following error message:
Error Code: 3522. A primary key index cannot be invisible |
MySQL invisible index system variables
To control visible indexes used by the query optimizer, MySQL uses the use_invisible_indexes
flag of the optimizer_switch
system variable. By default, the use_invisible_indexes
is off:
SELECT @@optimizer_switch; |
In this tutorial, you have learned about the MySQL invisible index, how to create an invisible index, and how to change the visibility of an existing index.
MySQL 8 supports invisible indexes, This allows you to on-demand enable/disable indexes from being used by MySQL optimizer. Now please don’t get confused with “disabled indexes“, “invisible indexes are not disabled indexes, MYISAM supports disabled indexes, ” , The disabled indexes halt maintenance of an index. Invisible indexes are a new feature in MySQL 8.0 , which mark an index unavailable for use by the optimizer. That means, Index will still be maintained and keep up-to-date as data is modified, but no queries will be permitted to make use of the index (even if the query uses a FORCE INDEX hint) .
Why we really love invisible indexes in MySQL 8.0?
- You want to make only one query to use that index, In this case “invisible index” is a great option
- On-demand indexing, You will have index (up-to-date with data) but you can make it visible or invisible. Even when optimizer force index, invisible indexes will not be invoked.
- Testing which index is efficient for many queries, You can test them by enabling invisible index and do not forget to disable them before testing with another invisible index, You can test index efficiency in production system (instant gratification indeed !)
How can you create MySQL invisible indexes?
There are two ways you can create invisible indexes:
Step1 is quite direct.
CREATE TABLE tab1 ( col1 int(10) DEFAULT NULL, col2 int(10) DEFAULT NULL, col3 int(10) DEFAULT NULL, KEY i_idx (col1), KEY idx_1 (col1,col2,col3) INVISIBLE ) ENGINE=InnoDB DEFAULT CHARSET=latin1
Step 2 is with “alter table script”
mysql> alter table tab1 alter index idx_1 invisible; Query OK, 0 rows affected (0.06 sec) Records: 0 Duplicates: 0 Warnings: 0
Using invisible index
mysql> show create table tab1 G; *************************** 1. row *************************** Table: tab1 Create Table: CREATE TABLE `tab1` ( `col1` int(10) DEFAULT NULL, `col2` int(10) DEFAULT NULL, `col3` int(10) DEFAULT NULL, KEY `i_idx` (`col1`), KEY `idx_1` (`col1`,`col2`,`col3`) /*!80000 INVISIBLE */ ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.01 sec)
Now, Let see we can forcefully make optimizer use the invisible index (here it is – idx_1)
mysql> explain select * from tab1 force index (idx_1) where col1=20 and col2=30; ERROR 1176 (42000): Key 'idx_1' doesn't exist in table 'tab1'
Let’s try, How we can forcibly make optimizer use the index i_idx (this works because index is not invisible)
mysql> explain select * from tab1 force index (i_idx) where col1=20 and col2=30; +----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+ | 1 | SIMPLE | tab1 | NULL | ref | i_idx | i_idx | 5 | const | 1 | 33.33 | Using where | +----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec)
We are converting the index “idx_1” visible to make optimizer forcibly use
mysql> alter table tab1 alter index idx_1 visible; Query OK, 0 rows affected (0.05 sec) Records: 0 Duplicates: 0 Warnings: 0
mysql> explain select * from tab1 force index (idx_1) where col1=20 and col2=30; +----+-------------+-------+------------+------+---------------+-------+---------+-------------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+-------+---------+-------------+------+----------+-------------+ | 1 | SIMPLE | tab1 | NULL | ref | idx_1 | idx_1 | 10 | const,const | 1 | 100.00 | Using index | +----+-------------+-------+------------+------+---------------+-------+---------+-------------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec) mysql>
We cannot alter Primary Key to invisible index:
mysql> create table tab3 -> (col11 int(10) not null, -> col22 int(10) not null, -> col33 int(10) not null, -> unique uidx(col11)); Query OK, 0 rows affected (0.10 sec) mysql> alter table tab3 alter index uidx invisible; ERROR 3522 (HY000): A primary key index cannot be invisible mysql>
Conclusion
MySQL 8.0 invisible index is an very interesting feature, This enables Database Architects / DBAs / Database Engineers to choose optimal indexing for MySQL performance and scalability. We are very excited about this feature, This makes several of our customer applications more optimal..
MySQL 8 invisible indexes (MySQL official documentation) – https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html