天天看點

MySQL SQL查詢語句優化

作者:貴哥說Java創業

優化 GROUP BY語句

預設情況下,MySQL對所有 GROUP BY col1,col2,... 的字段進行排序,這與在查詢中指定ORDER BY col1,col2,...類似。是以,如果顯式包括一個包含相同列的ORDER BY子句,對MySQL的實際執行性能沒有什麼影響。

如果查詢包括GROUPBY但使用者想要避免排序結果的消耗,則可以指定ORDER BY NULL 禁止排序。

優化嵌套查詢

有些情況下,子查詢可以被更有效率的連接配接(JOIN)替代。連接配接(JOIN)之是以更有效率一些,是因為 MySOL 不需要在記憶體中建立臨時表來完成這運輯上需要兩個步驟的查詢工作。

優化OR條件

對于含有 OR的查詢子句,如果要利用索引,則 OR 之間的每個條件列都必須用到索引如果沒有索引,則應該考慮增加索引。

優化分頁查詢

一般分頁查詢時,通過建立覆寫索引能夠比較好地提高性能。一個常見又非常頭痛的分頁場景是"limit 10000,20",此時 MySQL排序出前 10020條記錄後僅僅需要傳回第10001到10020條記錄。前10000 條記錄都會被抛棄,查詢和排序的代價非常高。

1、第一種優化思路

在索引上完成排序分頁的操作,最後根據主鍵關聯回原表在詢所需要的其他列内容。

例如電影表 film 根據标題 title 排序後取某一頁資料,直接查詢的時候,能夠從xplain 的輸出結中看到優化器實際上做了全表掃描,處理效率不高:

EXPLAIN SELECT film_id,description from film order by title limit 50,5           
MySQL SQL查詢語句優化

而按照索引分頁後回表方式改寫 SOL後,從explain 的輸出結果中已經看不到全表掃描了

EXPLAIN SELECT a.film_id,a.description from film a INNER JOIN (SELECT film_id from film order by title limit 50,5) b on a.film_id=b.film_id           
MySQL SQL查詢語句優化

這種方式讓MySQL掃描盡可能少的頁面來提高分頁效率

2.第二種優化思路

把 LIMIIT香詢轉換成某個位置的查詢。

例如,假設每頁 10 條記錄,查詢支付表 payment中按照租賃編号 rental_id 序排序的第42頁記錄,能夠看到執行計劃走了全表掃描:

explain SELECT * from payment order by rental_id desc limit 410,10           
MySQL SQL查詢語句優化

翻頁的過程中通過增加一個參數last_page record,用來記錄上一項最後一行的租賃編号rental_id,例如第41 頁最後一行的租賃編号rental id=15640:

explain SELECT * from payment WHERE rental_id<15640 order by rental_id desc limit 10           
MySQL SQL查詢語句優化

注意,這樣把 LIMIT m,n 轉換成LIMIT的查詢,隻适合在排序字段不會出現重發值的然境,能夠減輕分頁翻頁的壓力;如果排序字段出現大量重複值,而仍進行這種優化。那麼一面結果可能會丢失部分記錄,不适用這種方式進行優化。

繼續閱讀