目錄
Mysql優化(出自官方文件) - 第三篇
1 Multi-Range Read Optimization(MRR)
當使用二級索引進行多範圍查詢的時候,往往會導致對磁碟大量的隨機訪問,這就導致了區域性性非常差,因此,Mysql在遇到這種場景的時候,首先會利用二級索引查詢出所有的唯一索引,然後進行排序,在進行訪問,這樣子,就能大大的減少隨機訪問,眾所周知,對於傳統機械硬碟,順序讀的效率比隨機讀的效率要高很多。
需要注意的是:
MRR
優化不支援建立在virtual generated columns
上的二級索引,InnoDB
支援virtual generated columns
- 如果
Mysql
使用了這種優化,那麼在EXPLAIN
輸出結果的Extra
列會顯示Using MRR
如果查詢的結果完全可以通過
index
產生(covering index
, 覆蓋索引:指部分列資訊儲存在索引裡面)那麼將不會使用MRR
,
2 Block Nested-Loop(BNL) and Batched Key Access Joins(BKA)
BKA演算法可用於對joined table
的索引訪問和join buffer
,BKA支援inner join, outer join, semijoin,
以及nested outer join
,BKA
可以大大提高table scanning
的效能。
Join Buffer Management for Block Nested-Loop and Batched Key Access Algorithms
在
Mysql
中,Join buffer
分為regular buffer
和incremental buffer
,regular
可以理解為我們通常理解的buffer
,incremental
則是建立在regular
的前提下,儲存的部分列不是真正的資料,而是對上一個buffer
的引用。假設有一個場景,三表join,t1 join t2 join t3,Mysql
使用B1
作為t1
和t2
的join
臨時結果,B2
作為和t3
的結果,那麼通常來講:B1
是一個regular buffer
,Mysql
會把t1
和t2
的匹配結果儲存在B1
中,B1
中只會儲存匹配到的行,不會有任何多餘的行,並且,如果某一列是NULL
,Mysql
也不會為該列分配任何空間。B2
是一個incremental buffer
,Mysql
會把t3
中匹配的行存入到B2
中,然後再把B1
中t1
和t2
的連結儲存到B2
中,這樣子就避免了資料無意義的拷貝操作。
可以看到
incremental buffer
不是獨立的,一般來講,需要多個buffer
,第一個buffer
往往是regular buffer
,後面的buffer
才是incremental buffer
。Block Nested-Loop Algorithm for Outer Joins and Semijoins
當前的
Mysql BNL
演算法已經支援outer join
和semi join
了,當join
操作發生在join buffer
上的時候,通過將row
放到buffer
裡面會同時放入一個match flag
,表示join
的匹配情況。如果
Mysql
使用了BNL
,那麼將會在EXPLAIN
中體現如下,在Extra
列,結果為:Using join buffer (Block Nested Loop)
, 在Type
列,為:ALL
,index
, 或者range
.Batched Key Access Joins
BKA
通常用在有索引訪問的第二個join
上,在BNL join
演算法中,當第一個join
使用join buffer
產生了多個列,此時BKA
會把第一個join
結果的多個key
批量發給MRR
(第一節)介面,MRR engine
會使用更優化的方式進行table scan
,可以大大提升效率。在
EXPLAIN
中,如果使用BKA
,那麼Extra
列的結果為:Using join buffer (Batched Key Access)
,type
列的結果為:ref
oreq_ref
.