一些常見的【MYSQL優化】總結(一)

1、EXPLAN

善用EXPLAN來查看MYSQL的執行計劃。
這是一條SQL執行EXPLAN後的結果
以下這幾列是我們要重點關注的列:

  • type列:連接類型。一條好的SQL語句至少要達到range級別。杜絕出現all級別,type的級別有all、index、range、ref、eq_ref、const。從左到右,它們的效率依次是增強的,詳情可以到[EXPLAN中type總結]瞭解。(https://blog.csdn.net/dennis211/article/details/78170079)
  • key列:使用到的索引名,如果沒有使用到索引,值是NULL。(一些情況可以強制使用索引)
  • key_len列:使用到的索引的長度。
  • rows列:掃描的行數,該值是預估值。
  • Extra列:詳細說明。常見的不太友好的值有:Using filesort,Using temporary。

2、SQL語句中IN包含的值不應該過多

MYSQL對於IN做了相應的優化,即將IN中的常亮全部存儲在一個數組裏面,而且這個數組是排好序的。但是如果數值較多,產生的性能損耗也是較大的。對於連續的數值:例如 select id from table_name where num in (1,2,3),能用BETWEEN的時候就不用IN了;也可以使用連接來代替。

3、SELECT語句必須指明字段名稱

SELECT * 增加了很多不必要的消耗(cpu,io,內存,網絡帶寬等);增加了使用覆蓋索引的可能性;而且在代碼的維護上,在增加字段之後,Mybaties可能會發生錯誤。所以要求直接在SELECT後加字段名。

4、當只需要查詢一條數據的時候,使用limit1

首下這樣可以使EXPLAN中的type列達到const類型,其次在出現一些特殊情況,查詢的數據多於一條的時候,防止Mybaties發生

executor.ExecutorException: Statement returned more than one row, where no more than one was expected.

異常。(預計的結果爲對象,結果查詢到一個集合)

5、如果排序的字段沒有用到索引,儘量別用它進行排序。

6、如果限制條件中有字段沒有索引,儘量少用OR。

OR兩邊的字段中,如果一個不是索引字段,會導致該查詢不走索引的情況,很多時候用 union all或者是union來代替OR。

7、儘量用union all 代替 union

union 和 union all 的差異主要是前者需要將結果集合並後再進行唯一性過濾操作,這樣會涉及到排序,增加大量的CPU運算,加大資源消耗及延遲。當然,union all的前提條件是兩個結果集沒有重複數據。

8、不適用ORDER BY RAND()

這種類似的操作可以在代碼中進行。

9、區分IN和EXISTS,NOT IN和NOT EXISTS

SELECT * FROM 表A WHERE id IN (SELECT id FROM 表B)

已上語句相當於

SELECT * FROM 表A WHERE EXISTS (SELECT * FROM 表B WHERE B.id = A.id)

區分IN和EXISTS主要造成的是驅動順序的改變(這是性能變化的關鍵),如果使用EXISTS,那麼是將外層表作爲驅動表,先被訪問,如果是IN,那麼會先執行子查詢。所以In合適與外表大於內表的情況。EXISTS適合於外表大於內表的情況。

關於NOT IN 和 NOT EXISTS 推薦使用NOT EXISTS。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章