在上一篇中,咱們簡單的介紹了一下 InnoDB 引擎的索引類型,這一篇咱們繼續學習 InnoDB 的索引,聊一聊索引策略,更好的利用好索引,提高數據庫的性能,主要聊一聊覆蓋索引、最左前綴原則、索引下推。java
覆蓋索引是指在普通索引樹中能夠獲得查詢的結果,不須要在回到主鍵索引樹中再次搜索。mysql
創建以下這張表來演示覆蓋索引:sql
mysql> create table T ( ID int primary key, age int NOT NULL DEFAULT 0, name varchar(16) NOT NULL DEFAULT '', index age(age)) engine=InnoDB;
複製代碼
咱們執行select * from T where age between 13 and 25
語句,這條語句的執行流程大概爲:數據庫
若是咱們將語句換爲 select ID from T where age between 13 and 25
,執行這條語句時,在 age 索引樹上就能夠查詢到 ID 的值,省去了上面的回表操做,這樣就減小了搜索次數,提高了查詢效率。微信
這時候的 age 索引樹已經能夠知足咱們的查詢需求,age 索引就稱爲覆蓋索引。性能
覆蓋索引是經常使用的數據查詢優化技術,能夠極大的提高數據庫性能,有如下幾個緣由:學習
最左前綴原則是創建在聯合索引之上的,若是咱們創建了聯合索引,咱們不須要使用索引的所有定義,只要用到了索引中的最左邊的那個字段就可使用這個索引,這就是 B-tree 索引支持最左前綴原則。優化
創建以下這張表來解釋最左前綴原則:spa
mysql> create table T ( ID int primary key, age int NOT NULL DEFAULT 0, name varchar(16) NOT NULL DEFAULT '', ismale tinyint(1) DEFAULT NULL, email varchar(64), address varchar(255), KEY `name_age` (`name`,`age`)) engine=InnoDB;
複製代碼
咱們創建了聯合索引 name_age,如今,假設咱們有一下三種查詢情景:code
在這三種狀況中,第一種狀況能夠利用到 name_age 這個聯合索引,加速查詢,能夠看出,咱們並無 使用索引的所有定義,只要知足最左前綴,就能夠利用索引來加速檢索。這個最左前綴能夠是聯合索引的最左 N 個字段,也能夠是字符串索引的最左 M 個字符。
若是咱們將索引的順序調整爲KEY
name_age(
age,
name)
,那麼上面三種狀況都使用不到這個聯合索引。
維護索引須要代價,因此有時候咱們能夠利用「最左前綴」原則減小索引數量。
索引下推優化是 MySQL 5.6 引入的, 能夠在索引遍歷過程當中,對索引中包含的字段先作判斷,直接過濾掉不知足條件的記錄,減小回表次數。
創建以下這張表來解釋索引下推:
mysql> create table T ( ID int primary key, age int NOT NULL DEFAULT 0, name varchar(16) NOT NULL DEFAULT '', ismale tinyint(1) DEFAULT NULL, email varchar(64), address varchar(255), KEY `name_age` (`name`,`age`)) engine=InnoDB;
複製代碼
在表中創建了 name、age 的聯合索引,咱們執行 select * from T where name like '張%' and age=10 and ismale=1;
語句,咱們已經知道了B-tree 索引的最左前綴原則,因此將會用到 name_age 索引,由於索引下推優化,會在 name_age 索引樹上判斷 name 和 age 是否知足。
根據咱們上面的執行語句,會在 name_age 索引樹上查找 name 以 '張' 開頭的而且 age = 10 的數據,而後在回到主鍵索引樹中查詢所須要的信息,並非全部 name_age 索引樹上查找 name 以 '張' 開頭的數據都回主鍵索引樹中查詢數據,這樣就減小了一些沒必要要的查詢。
假設咱們的數據以下圖所示:
在 name_age 索引樹中有四條符合 name 以 '張'開頭的數據,若是沒有索引下推,則須要回到主鍵索引樹上判斷 age 是否等於 10 ,這樣就須要回表四次,而有了索引下推以後,在 name_age 索引樹上就判斷 age 是否等於 10 ,只須要回表兩次,這樣就減小了回表次數,提高了查詢性能。
以上就是關於 InnoDB 引擎中的索引策略,感謝您的閱讀,但願這篇文章對您的學習或者工做有所幫助。
目前互聯網上不少大佬都有 MySQL 相關文章,若有雷同,請多多包涵了。原創不易,碼字不易,還但願你們多多支持。若文中有所錯誤之處,還望提出,謝謝。
歡迎掃碼關注微信公衆號:「平頭哥的技術博文」,和平頭哥一塊兒學習,一塊兒進步。