MySQL 8.0 雖然發布很久了,但可能大家都停留在 5.7.x,甚至更老,其實 MySQL 8.0 新增了許多重磅新特性,比如堆疊長今天要介紹的 "隱藏索引" 或者 "不可見索引",
隱藏索引是什么鬼?
隱藏索引 字面意思就是把索引進行隱藏,即不可見,它不是用來查詢優化的,所以它不會被優化器使用到,隱藏索引適用于除主鍵索引(顯示或者隱式設定)之外的索引,意味著主鍵索引是不能通過任何方式隱藏的,
MySQL 資料庫默認創建的索引都是可見的,要顯式控制一個索引的可見性,可以在 CREATE TABLE,CREATE INDEX 或 ALTER TABLE 的索引定義命令中使用 VISIBLE 或 INVISIBLE 關鍵字,
如下面示例所示:
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;
要變更現有索引的可見性,可以在 ALTER TABLE ... ALTER INDEX 命令中使用 VISIBLE 或 INVISIBLE 關鍵字,
年齡索引變更為不可見(隱藏):
ALTER TABLE javastack ALTER INDEX age_idx INVISIBLE;
年齡索引變更為可見:
ALTER TABLE javastack ALTER INDEX age_idx VISIBLE;
怎么知道一個表中的索引是可見還是不可見,可以從 INFORMATION_SCHEMA.STATISTICS 表,或者 SHOW INDEX 命令輸出中獲得,例如:
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 |
+------------+------------+
隱藏索引有什么用?
從上面隱藏索引介紹我們知道,隱藏索引可以不被優化器所使用,那么我們可以把某個表的某個索引設定隱藏,然后再測驗 SQL 陳述句的查詢性能,
即可以利用隱藏索引快速測驗洗掉索引后對 SQL 查詢性能的影響,而無需進行索引洗掉、重建操作,如果需要該索引,再設定可見就好了,這在大表測驗中無疑非常有用,因為對于大表索引的洗掉和重新添加很耗性能,甚至影響表的正常作業,
隱藏索引設定
如果一個索引被設定成隱藏了,但實際上又需要被優化器所使用,有幾種表索引情況缺失對查詢造成的影響:
1)SQL 查詢陳述句中包含了索引提示指向不可見索引會發生錯誤;
2)性能模式資料中顯示了受影響 SQL 查詢陳述句的負載增高;
3)SQL 查詢陳述句進行 EXPLIAN 時出現了不同的執行計劃;
4)SQL 查詢陳述句出現在了慢查詢日志中(之前沒有出現);
系統變數 optimizer_switch 的 use_invisible_indexes 標志的值,控制了優化器執行計劃構建時是否使用隱藏索引,
如果 use_invisible_indexes 值設定為 off 關閉狀態(默認值),優化器默認會忽略隱藏索引,即和加入該引數之前的效果一樣,
如果 use_invisible_indexes 值設定為 on 打開狀態,隱藏索引仍然保持不可見,但優化器會把隱藏索引加入到執行計劃的構建中,
如果想要在某條單個 SQL 查詢陳述句上啟用隱藏索引,可以使用 SET_VAR 優化器提示來臨時更新 optimizer_switch 的值,如下所示:
mysql> EXPLAIN SELECT /*+ SET_VAR(optimizer_switch = 'use_invisible_indexes=on') */
> age, weight FROM javastack WHERE weight >= 150\G
*************************** 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 >= 150\G
*************************** 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
索引的可見性不會影響索引的自身維護,例如,不管索引是可見還是不可見,每次表資料行的更改索引都會更新,并且唯一索引也可防止插入重復資料,
沒有顯式主鍵的表如果在 NOT NULL 列上有任何一個唯一索引,則仍可能成為有效的隱式主鍵,在這種情況下,第一個這樣的索引會對表資料行施加與顯式主鍵相同的約束,并且該索引不能設定為不可見,
如以下表的定義:
CREATE TABLE javastack (
age INT NOT NULL,
weight INT NOT NULL,
UNIQUE weight_idx (weight)
) ENGINE = InnoDB;
該表定義不包含任何顯式主鍵,但是 weight 列為 NOT NULL,在該列上創建的唯一索引在資料行上與主鍵具有相同的約束,并且不能使其不可見:
mysql> ALTER TABLE javastack ALTER INDEX weight_idx INVISIBLE;
ERROR 3522 (HY000): A primary key index cannot be invisible.
假設現在我們將一個顯式主鍵添加到表中:
ALTER TABLE javastack ADD PRIMARY KEY (age);
顯式主鍵不能設定為不可見,此時,weight 列上的唯一索引不再充當隱式主鍵,因此可以使其設定不可見,
mysql> ALTER TABLE javastack ALTER INDEX weight_idx INVISIBLE;
Query OK, 0 rows affected (0.03 sec)
總結
本文介紹了 MySQL 8.0 中的新特性:隱藏(不可見)索引,這個索引并不是新加的索引型別,而是可以控制索引是否加入到執行計劃的構建之中,
在實際生產中也可以利用隱藏索引進行 SQL 陳述句的性能測驗,或者對索引進行邏輯洗掉,以及索引的灰度發布測驗等,用處還是蠻大的,
本次的分享就到這里了,希望對大家有用,覺得不錯,在看、轉發分享一下哦~
最后,MySQL 系列教程還會繼續更新,關注Java技術堆疊公眾號第一時間推送,還可以在公眾號選單中獲取歷史 MySQL 教程,都是干貨,
參考檔案:
https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html
話說你們用的 MySQL 哪個版本呢?來投票一下!
另外,關注公眾號Java技術堆疊,在后臺回復:面試,可以獲取我整理的 MySQL 系列面試題和答案,非常齊全,
著作權申明:本文系公眾號 "Java技術堆疊" 原創,原創實屬不易,轉載、參考本文內容請注明出處,禁止抄襲、洗稿,請自重,尊重他人勞動成果和知識產權,
近期熱文推薦:
1.Java 15 正式發布, 14 個新特性,重繪你的認知!!
2.終于靠開源專案弄到 IntelliJ IDEA 激活碼了,真香!
3.我用 Java 8 寫了一段邏輯,同事直呼看不懂,你試試看,,
4.吊打 Tomcat ,Undertow 性能很炸!!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/252443.html
標籤:Java
上一篇:Java學習-JDBC
