SQL優化 MySQL版 -分析explain SQL執行計划
作者 Stanley 羅昊
【轉載請注明出處和署名,謝謝!】
首先我們先創建一個數據庫,數據庫中分別寫三張表來存儲數據;
course:課程表
teacher:教師表
teacherCarid:教師證表
現在我把這三張表連起來查,查詢條件:查詢課程編號為2或教師證編號為3點老師信息;
通過這個例子,我們就可以把explain里面的參數一個一個的講講:
首先這個條件的主干是查詢老師信息;
sql語句:select t.* From teacher t INNER JOIN course c INNER JOIN teachercarid te WHERE t.tid = c.cid AND t.tcid = te.tcid AND (c.cid = 2 or te.tcid = 3);
執行結果:
SQL語句很簡單,我們不關心這個,我們關心的是在它前面加explain:
explain select t.* From teacher t INNER JOIN course c INNER JOIN teachercarid te WHERE t.tid = c.cid AND t.tcid = te.tcid AND (c.cid = 2 or te.tcid = 3);
執行看結果:
先看id:
id此時此刻都是1,它們都對應我們的表 te 是我們的教師證表 t 就是教室表 c 是課程表
由此可見,我們編寫的SQL語句它底層是先執行教師證表的,然后執行教室表,最后再執行課程表;
那這是為什么呢?
我們來分析一下數據:
course:課程表 有三條數據
teacher:教師表 有三條數據
teacherCarid:教師證表 有四條數據
難道是數據越少就先執行誰?我們不妨來做個試驗看看,我再加幾條數據:
現在我們的數據變更為:
course:課程表 有三條數據
teacher:教師表 有四條數據
teacherCarid:教師證表 有六條數據;
我們再看它的執行計划:
通過試驗我們發現,確實誰少就先執行誰,但是我我們卻發現,表的執行順序是因數量的個數改變而改變,那它的原因是什么呢?為什么表的執行順序會跟隨個數而改變呢?
笛卡爾積
我們現在假設a b 兩張表,a里面有三條數據,b里面有六條數據,最后他倆相乘 = 18;
我們假設現在有 a b c三張表,第一張表 a 是三條數據 第二張表是3條數據第三表的數據是4,那它們的笛卡爾積 2*3 = 6 6再*4 = 24;
這個時候我們換一下位置 a 是四條數據 b 是三條數據 c 是兩條數據,我們再來算一下它們的笛卡爾積:3*4 = 12 *2 = 24;
我們發現兩者結果都沒有變,但是中間結果變了,第一次計算笛卡爾積時 第一次計算2*3 =6,第二次計算笛卡爾積時3*4 = 12,因為6比12小索所以它就先執行;
為什么在圖上,c先執行的原因是 c * t (3*4 = 12)te 是6,所以比較大,就向后放;
結論:數據小的表,會優先查詢;
ID值越大越優先執行
id值相同,就從上往下依次執行,如果不相同,那就從下往上執行,因為id值越大,它就越往下排列;
Select_type
PRIMARY:包含查詢SQL中的子查詢(最外層)
SUBQUERY:包含子查詢SQL中的子查詢(非最外層)
Simple:簡單查詢(一個SQL語句里面不包含子查詢,union)都是簡單查詢
derived:衍生查詢 觸發子衍生查詢只有兩種:
1.在from子查詢中,只有一張表
2.在from子查詢中如果有兩張表,比如 tablie1 union table2,則table1就是衍生查詢;
今日感悟:
如果你要燒一壺開水,生火到一半時發現柴不夠了,你應該怎么辦?
“趕緊去找?”
“去鄰居接一下?”
“趕緊去買柴火?”
如果是我,我會把壺里的水倒掉一些,
懂得舍棄的人,或許能得到的會更多