mysql(三) 慢查詢分析(二)
在一般的查詢中,都要求盡量圍繞創建的索引進行。針對索引,常用的有主鍵索引,單列索引,組合索引,索引合並等。
在評價索引時,關鍵看區分度。索引區分度=索引列唯一值/表記錄數。
如果在區分度很低的列上建索引,那索引掃描的rows會相當大,該索引的性能表現就基本接近全表掃描了。
- 主鍵索引
是一種特殊的唯一索引,不允許有空值。
- 單列索引
針對表的單一列設置索引。
- 組合索引
針對表的多列按列順序設置索引。在組合索引中,基於BTree的原理,存在一個最左前綴匹配原則。如下索引(mobile_price_create_index):
能用到索引的場景:
mobile=a時,可以用到索引的第一列。
mobile=a and create=c時,只能用到索引的第一列。
mobile=a and price=b時,可以用到索引的兩列。
mobile=a and price=b and create =c時,可以用到索引的三列。
mobile=a and price > b and create=c時,可以用到索引的前兩列。
mobile>a and price =b and create=c時,只能用到索引的第一列。
mobile=a and price=b and create>c時,可以用到索引的三列。
order by a時,可以用到索引。
mobile=a order by price時,第一列過濾,第二列排序,可以用到索引。
order by mobile desc,price desc時,此時兩列排序順序一致,可以用到索引。
mobile > a order by a時,範圍查詢在第一列,排序在第一列,可以用到索引。
用不到索引的場景:
price=b and create=c時,用不到索引。
order by b時,不能用到索引。
order by mobile desc,price asc時,此時兩列排序順序不一致,用不到索引。
mobile > a order by price時,範圍查詢在第一列,排序在第二列,第二列用不到索引。
這裏要聲明一個誤區,參數的順序不影響使用組合索引。mobile=a and price=b and create =c 與 create=c and price=b and mobile=a是等價的。
索引的創建要根據最常使用的參數來設定,使用時,要盡量貼合索引來實現邏輯。
- 索引合並
針對單表的查詢,可以支持查詢條件使用多個索引,然後對查詢結果進行交集,並集,有序並集等處理。
mysql支持在針對單表的查詢時,合並多個索引的查詢結果。
如下索引結構:
執行如下執行計劃:
explain select * from trade_order where gmt_create >‘2018-06-02 13:25:23‘ or mobile =‘mobile-3679‘;
這個sql中使用了合並索引,分別針對gmt_create和mobile使用了2個索引。然後將其結果集求並集之後排序。
針對or的查詢條件,組合索引不能起到有效的作用。此時可以通過在條件上建單獨的索引,然後合並使用。
針對and的查詢條件,創建組合索引效率更好,退而求其次時,可以選擇創建多個索引,然後合並使用。
那如果出現慢查詢,可以根據執行計劃,看是否未命中索引,命中的索引區分度是否足夠,組合索引是否滿足最左前綴的原則,如果索引只能命中一部分,是否可以通過合並索引的方式改進sql。
mysql(三) 慢查詢分析(二)