5 MySQL基於索引的優化

2021-09-03 02:54:59 字數 1931 閱讀 4182

建表語句如下:

mysql> create table t (

id int primary key,

k int not null default 0,

s varchar(16) not null default '',

index k(k))

engine=innodb;

idks

1001

『aa』

2002

『bb』

3003

『cc』

5005

『ee』

2006

『ff』

2007

『gg』

生成的索引樹入下圖

如果執行:select * from t where k between 3 and 需要執行幾次樹的搜尋操作,會掃瞄多少行?

該語句執行流程如下:

在 k 索引樹上找到 k=3 的記錄,取得 id = 300;

再到 id 索引樹查到 id=300 對應的 r3;

在 k 索引樹取下乙個值 k=5,取得 id=500;

再回到 id 索引樹查到 id=500 對應的 r4;(回到主鍵稱為回表)在 k 索引樹取下乙個值 k=6,不滿足條件,迴圈結束。

如果執行的語句是 select id from t where k between 3 and 5,這時只需要查 id 的值,而 id 的值已經在 k 索引樹上了,因此可以直接提供查詢結果,不需要回表。也就是說,在這個查詢裡面,索引 k 已經「覆蓋了」我們的查詢需求,我們稱為覆蓋索引。

由於覆蓋索引可以減少樹的搜尋次數,顯著提公升查詢效能,所以使用覆蓋索引是乙個常用的效能優化手段。

create table `tuser` (

`id` int(11) not null,

`id_card` varchar(32) default null,

`name` varchar(32) default null,

`age` int(11) default null,

`ismale` tinyint(1) default null,

primary key (`id`),

key `id_card` (`id_card`),

key `name_age` (`name`,`age`)

) engine=innodb

以姓名(name)和年齡(age)簡歷聯合索引如下圖:

(name,age索引圖)

如果只根據name查詢那麼,可以復用該聚合索引。不需要再在name上單獨建索引了。

第一原則是,如果通過調整順序,可以少維護乙個索引,那麼這個順序往往就是需要優先考慮採用的。那麼,如果既有聯合查詢,又有基於 name、age各自的查詢呢?查詢條件裡面只有 age 的語句,是無法使用 (name,age) 這個聯合索引的,這時候你不得不維護另外乙個索引,也就是說你需要同時維護 (name,age)、(age) 這兩個索引。

這個時候就得考慮空間了。假設name 欄位是比 age 欄位大的 ,那我就建議你建立乙個(name,age) 的聯合索引和乙個 (age) 的單字段索引。僅多了age索引樹比如執行以下語句:

mysql> select * from tuser where name like '張 %' and age=10 and ismale=1;
mysql5.6以後會在聚簇索引樹中過濾掉age不滿足條件的而不用回表查詢,稱為索引下推。如圖:

5 mysql索引注意事項

假設有乙個聯合索引 idx name,gender explain select from table where name 此時會在執行計畫中發現索引會生效.而explain select from table where gender 此時的聯合索引不會生效.當我們使用組合索引的第乙個欄位去查詢...

mysql優化(5) 索引優化

建立合理地索引能夠提公升資料庫的查詢效率,但是如果建立的索引不合理,不僅會降低資料庫的插入 修改 刪除的效率,而且會降低資料庫的查詢效率。其中最主要的是組合索引的建立和優化。mysql允許在相同的列上建立多個索引,無論索引是否有實際的意義。且索引一旦被建立,就需要mysql單獨維護重複的索引,且my...

5 Mysql效能分析

1.慢查詢日誌 2.檢視問題sql的執行計畫 3.優化慢sql 4.檢視慢sql執行時的效能使用情況 5.調整系統引數 6.提公升伺服器硬體1.引數,開啟sql sql set global slow query log on set global long query time 1 配置檔案 my...