MySQL提高篇(五)--- SQL語句優化

優化insert語句:

  如果需要對同一張表插入多條數據,可以將多條插入語句合併爲一條:

insert into tb_user values(1,'Peter');
insert into tb_user values(2,'Tom');
insert into tb_user values(3,'Jon');

  優化後:

insert into tb_user values(1,'Peter'),(2,'Tom'),(3,'Jon');
優化order by語句

  在mysql中,實際上可以認爲有兩種排序方式,一種是按照索引排序,另外一種是從磁盤取數據到內存再進行filesort排序。當使用explain查看sql的執行計劃時,如果extra字段出現了Using filesort;即表示數據排序使用到了Filesort排序,它比按索引排序的效率低,因爲按索引排序其實從磁盤中取出的數據就是有序的,不需要在內存中做額外的排序操作
  瞭解了這個知識之後,我們就知道爲什麼要讓order by字段和where條件中使用同樣的索引了,只要order by的順序與索引順序相同,mysql就不需要另外在內存中做額外的排序操作。

優化Filesort

 兩次掃描算法:
  Mysql4.1之前,是使用這種方式排序,它首先根據條件取出排序字段和對應的行指針信息,然後在sort buffer中排序,如果sort buffer大小不夠,則在臨時表中存儲排序結果,完成排序後,再根據行指針回表讀取記錄,因此該操作會導致大量的隨機IO操作。

 一次掃描算法:
  這種方式是一次性取出所有要查詢字段,然後在排序區sort buffer中排序後輸出結果集,它的內存開銷比較大。

  Mysql通過比較系統變量max_length_for_sort_data的大小和查詢的數據集大小進行比較,來選擇使用哪種排序算法。所以我們可以適當提高sort_buffer_size和max_length_for_sort_data的大小來提高排序的效率。

優化group by語句

  由於group by 後的分組結果實際上也會進行排序,所以我們也需要在group by的字段上使用與where條件一樣的索引,另外,如果結果不需要排序,可以通過 order by null 來阻止排序以提高效率。

優化嵌套查詢

  由於子查詢需要在內存中創建臨時表來完成查詢功能,所以其查詢效率比對應的關聯查詢效率低,因此建議使用關聯查詢替代子查詢。(注意:有時候子查詢會被mysql優化器優化爲關聯查詢)

優化 or 條件查詢

  
在這裏插入圖片描述
查看sql的執行計劃

通過查看兩條語句的執行計劃,可以看到,union 連接比 or 條件查詢效率要高,所以我們應該儘量使用union 來代替or條件查詢。

優化分頁查詢

  對於一般的分頁查詢,通過創建覆蓋索引可以有效的提高查詢性能。但是假如需要查詢的是:

select username from t_user limit 2000000,10;

這種行偏移量較大的分頁查詢查詢效率低下,有哪些方法可以對其進行優化呢?
方法一:
  假如表是主鍵自增類型的,可以將上面的sql語句轉換爲:

select username from t_user where id > 2000000 limit 10;

這種情況有一個條件,就是表的主鍵是自增的且表中的記錄不會進行物理刪除
方法二:
  表不滿足上面的兩個條件,此時的優化方式爲:

select username from t_user u,(select id from t_user order by id limit 2000000,10) t where u.ud = t.id; 

即在主鍵上完成排序分頁功能然後關聯回自身進行查詢。

發佈了28 篇原創文章 · 獲贊 4 · 訪問量 1318
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章