MySQL 怎么变快_如何让mysql索引更快一点
在 InnoDB 中,從二級索引回到主鍵索引查詢數據,這個過程稱作回表過程,而且這個回表過程是可以被優化的,這個優化就是利用覆蓋索引。
先說結論,如果一個索引的字段包含了所有要查詢的字段,這個索引就稱作覆蓋索引,覆蓋索引可以減少回表過程,能有效提高查詢效率。
前面我們有說過,在 InnoDB 中數據都是保存在 B+ 樹上,主鍵索引保存了整行記錄,二級索引保存了主鍵的值。
一次查詢操作,要么是遍歷主鍵索引,要么是遍歷二級索引,要么就是先遍歷二級索引得到主鍵 id 的值,然后再到主鍵索引上通過主鍵 id 查找滿足要求的記錄。
如果只遍歷一次 B+ 樹就能獲取到我們要的數據,即沒有回表過程,這個效率顯然是不錯的,這就是覆蓋索引的優勢。下面看個具體的例子。
mysql> create table user(
id int(11) primary key,
name varchar(20) not null,
age int(11),
sex int(11),
index (age)) engine=InnoDB;
依然是新建一個表,創建索引,插入一些測試數據,注意這里只是為了解釋說明覆蓋索引,并不表示 mysql 的真實執行方式,因為會涉及到 mysql 的優化器機制,這里暫且不說了,以后再寫。
1 bob 16 1
2 kom 19 0
3 gum 18 1
4 tt 20 1
5 yy 25 1
創建一個 user 表,給 age 字段添加一個二級索引,并插入上面五條數據,然后看下面這條查詢語句。
select name from user where age between 18 and 21
我們來分析下這條 sql 的執行過程:
1、age 字段上有索引,mysql 會先到 age 字段的 B+ 樹上找到滿足條件的第一個葉子節點(age=19),這個葉子節點上保存了對應主鍵 id 的值 2,然后再到主鍵索引上找到 id 為 2 的這條記錄,同時把 name 字段拿出來。
2、重復第一步的操作,繼續從 age 索引上的葉子節點往后遍歷找出滿足條件的第二個葉子節點,同樣回到主鍵上拿出 name 字段的值,直到遍歷到不滿足條件的葉子節點(age=25)。
也就是說,這條 sql 語句雖然用到了索引,但是 age 索引上并沒有要查詢的 name 字段,所以只能回表到主鍵索引上查出 name 字段,所以這個過程其實是遍歷了個兩個 B+ 樹。
那么我們刪除 age 這個單列索引,創建一個覆蓋索引 (age,name), 把要查詢的 name 字段也添加到索引中來。
#刪除原索引
drop INDEX age on USER
#新建覆蓋索引
ALTER TABLE USER add index age_name(age,name)
由于現在這個覆蓋索引上的字段包含了要查詢的 age 和 name 字段,免去了到主鍵索引上查詢數據的過程,其實也就是只遍歷了一個 B+ 樹,可以大大提升查詢效率。
添加索引雖然能提升查詢效率,但索引也是需要占用額外空間的,而且索引還需要維護成本,所以通常加不加索引需要根據實際需求來權衡。
總之,在設計索引或者優化 sql 語句的時候,要盡量避免回表操作,所以使用覆蓋索引是一種常用的 sql 優化手段。
所以我們平時寫 sql 語句的時候,select 后面只寫查詢需要用到的字段,去掉不需要的字段,避免回表操作。
有問題歡迎大家留言交流,原創不易,如果文章對你有幫助,歡迎點贊,感謝支持。
總結
以上是生活随笔為你收集整理的MySQL 怎么变快_如何让mysql索引更快一点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql有那么多存储引擎_MySQL的
- 下一篇: mysql+主从复制重做_XtraBac