優化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;
即在主鍵上完成排序分頁功能然後關聯回自身進行查詢。