MySQL查詢優化

2021-10-09 02:59:10 字數 3324 閱讀 9134

1.用小表驅動大表

2.order by關鍵字優化

3.group by關鍵字優化

用資料量小的表驅動資料量大的表。為什麼要用小表驅動大表?假設a表資料是1000條,b表20條,如果用a表驅動要迴圈1000次(請求和斷開)才能查詢出來,用b表則只需要20次

用for迴圈和sql語句說下怎麼用小表驅動大表:

1.外層迴圈有5條資料,相當於資料量比較少的驅動表,內層有1000條資料,相當於大表

2.使用子查詢小表驅動大表說明

select * from a where id in (select id from b)      //b表資料少於a表時,用in優於exists,這裡b表應為驅動表

select * from a where exists(select 1 from b where a.id=b.id)    //當a表資料少於b表時,用exists優於in,這裡a表應為驅動表

注:ab表關聯的id欄位應建立索引

3.使用join關鍵字的小表驅動大表

select * from a a left join b b a.id=b.id  //此時a應為驅動表

exists可能都用的比較少,這裡解析下:將主查詢的資料,放到子查詢中做條件驗證,根據驗證結果(true或false)來決定主查詢的結果是否得以保留。

1.order by子句盡量使用index方式排序,避免使用filesort方式排序。mysql支援兩種方式排序,filesort和index,index效率高,它指mysql掃瞄索引本身完成排序。filesort效率較低,它是指mysql把資料存到記憶體中,然後通過相應的排序演算法,將取得的資料在記憶體中進行排序

2.order by滿足兩種情況會使用index方式排序:1.order by語句使用索引最左字首法則。2.使用where子句與order by子句條件列組合滿足索引最左字首法則

3.盡可能在索引列上完成排序操作,遵照索引建的最左字首法則。如果不在索引列上,filesort有兩種演算法:雙路排序和單路排序

雙路排序:mysql4.1之前是使用雙路排序,字面意思就是兩次掃瞄磁碟,最終得到資料,第一次io讀取行指標和order by列,對他們進行排序,然後第二次io掃瞄已經排序好的列表,按照列表中的值重新從列表中讀取對應的資料輸出。

單路排序:從磁碟讀取查詢需要的所有列,按照order by列在buffer(緩衝區)對它們進行排序,然後掃瞄排序後的列表進行輸出,它的效率更快一些,避免了二次io。並且把隨機io變成了順序io,因為把每一行都儲存在記憶體中,所以會使用更多的空間。 這樣就會出現乙個sort_buffer容量不足的問題。

因為在sort_buffer中,單路排序比雙路排序要多占用很多空間,因為單路排序是一次性把所有字段取出放到buffer中,所以有可能去除的資料總大小超出了sort_buffer的容量,導致每次只能取soer_buffer容量大小的資料進行排序(建立tmp檔案,多路合併),排序完再取sort_buffer容量大小的資料,再排序,這樣重複多次,從而會有多次i\o

如果無法避免出現filesort那麼我們就要考慮下優化策略來提高order by的速度

1.order by時select * 是乙個大忌,只查詢需要的字段就夠了,這點很重要。在這裡的影響是:

1.1當查詢的字段大小總和小於max_length_for_sort_data而且排序字段不是text|blob型別時,會用單路排序,否則用雙路

1.2兩種演算法的資料都有可能超出sort_buffer的容量,超出之後,會建立tmp檔案進行黑幫排序,導致多次i\o,但是用單路排序演算法的風險會更大一些,所以要提高sort_buffer_size

2.嘗試提高sort_buffer_size,不管用哪種演算法,提高這個引數都會提高效率,當然要根據系統的能力取提高,因為這個引數是針對每個程序的

3.嘗試提高max_length_for_sort_data,提高這個引數,會增加用單路排序的概率。但是如果設的太高,資料總容量超出sort_buffer_size的概率就增大,明顯症狀是高的磁碟i\o活動和低的處理器使用率

下面演示下避免出現filesort

為了更好演示例項,先建立好索引

alter table users add index idx_users_account***username(account,***,username);
建立的索引順序是account→***→username,所以order by後面的索引順序必須是account→***→username,當然也可以不使用***或者***和username。

如果在where後面使用了account作為條件,那麼order by後面可以只用 ***,username或者只用***,當然也可以用account,但是必須要根據索引建立時的順序進行排序

首先看看正確的例子,沒有出現filesort的

還有乙個弄不明白的情況,當where使用了account和***。order by裡account和***使用了公升序排序,username使用了降序,這樣沒有出現filesort,就是說where裡用到的索引字段,在order by後面可以反過來排序。這個不知道為啥,知道的大神麻煩解科普下

看看錯誤的例子,出現了filesort

1.沒有根據索引建立的順序直接使用了username,而沒有用上***字段

2.如果在where後面加上***作為條件就不會出現filesort,至於為什麼暫時還沒弄清楚咋回事

參考上面order by

查詢優化(MySQL優化查詢)

關聯查詢太多join 設計缺陷或不得已的需求 資料庫伺服器調優及各個引數設定不適當 緩衝 執行緒數等 慢查詢日誌 找出執行速度慢的sql語句 慢查詢的開啟並捕獲 explain 慢sql分析 show profile查詢sql在mysql伺服器裡面的執行細節和生命週期情況 sql資料庫伺服器的引數調...

mysql統計查詢優化 Mysql查詢優化

效能涉及的層面很多,但是在操作層面,主要有表結構設計優化 索引優化和查詢優化 查詢的生命週期大致可以分為,從客戶端 到服務端 在伺服器上解析 生成執行計畫 執行 返回結果給客戶端 sql執行流程 具體優化技巧 1.消除外連線 2.消除子查詢 盡量用join代替子查詢,雖說mysql查詢優化器會進行優...

MySQL優化 查詢優化

在每乙個消耗大量時間的查詢中,都能看到一些不必要的額外操作 某些操作被額外地重複了很多次 某些操作執行得太慢等。優化查詢的目的就是減少和消除這些操作所花費的時間。查詢效能低下最基本的原因是訪問的資料太多。所以需要考慮是否向資料庫請求了不需要的資料 1 多表關聯時,或獲取單錶資料時,盡量避免不加思考地...