對於鏈接查詢,EXPLAIN的extra字段出現using join buffer,表示使用了鏈接緩存,保證JOIN語句中被驅動表上JOIN條件字段已經添加索引;java
LEFT JOIN 條件用於肯定如何從右表搜索行,左邊必定有,因此右邊的關鍵是要創建索引;左鏈接索引加在右表; RIGHT JOIN條件用於肯定如何從左表搜索行,右邊必定有,左邊的關鍵是創建索引;左表創建索引;
關於慢查詢分析的步驟mysql
1.開啓慢查詢日誌,設置閾值,好比超過5秒就是慢sql,並將它抓出來 2.explain+慢sql分析 3.show profile查詢sql在mysql服務器裏面的執行細節和生命週期等 4.sql數據庫服務器的參數調優
小表驅動大表的解釋,下面有兩組循環;sql
第一組循環數據庫
for (int i = 5; ..) { for(int j = 1000;...) { } }
第二組循環緩存
for (int i = 1000;..) { for (int j = 5; ...) { } }
上面兩組循環,都是循環了5000次;對於數據庫而言,第一組循環比較好,由於第一組循環總共就建立了5個鏈接,不用頻繁的建立鏈接,釋放鏈接;bash
小表驅動大表,意思是小的數據集驅動大的數據集;服務器
EXISTS優化
select * from A where id in (select id from B) -- 等價於: -- for select id from B -- for select * from A where A.id = B.id
當B的數據集必須小於A表的數據集時,用 in 優於 exists;spa
select * from A where exists (select 1 from B where B.id = A.id) -- 等價於: -- for select * from A -- for select * from B where B.id = A.id
當A表的數據集小於B表的數據集時,用exists優於in;日誌
注意: A表與B表的字段id應創建索引;
SELECT ... FROM table WHERE EXISTS(subquery) 將主查詢的數據,放到子查詢中作條件驗證,根據驗證結果(TRUE 或FALSE)來決定主查詢的數據結果是否保留; EXISTS(subquery) 只返回TRUE或FALSE,所以子查詢中的SELECT * 也能夠時select 1 或select 'x',官方說法是實際執行時會忽略SELECT清單,所以沒有區別; EXISTS子查詢的實際執行過程可能通過了優化而不是咱們理解的逐條對比,若是擔心效率問題,可進行實際校驗以肯定是否有效率問題; EXISTS子查詢每每也能夠用條件表達式,其餘子查詢或JOIN來替代;