mysql - SQL 優化小結
阿新 • • 發佈:2021-01-19
優化批量插入資料:
- 資料來源,根據主鍵做好排序,再進行資料匯入:
mysql> load data local infile '/root/sql1.log' intotable `table_1` fields terminated by ',' lines terminated by '\n';
- 關閉唯一性校驗:
在匯入資料前執行SET UNIQUE_CHECKS=0,關閉唯一性校驗,在匯入結束後執行SET UNIQUE_CHECKS=1,恢復唯一性校驗,可以提高匯入的效率。
- 手動提交:
如果應用使用自動提交的方式,建議在匯入前執行SET AUTOCOMMIT=0,關閉自動提交,匯入結束後再執行SET AUTOCOMMIT=
insert語句優化:
- values多個:
INSERT INTO MyTable ( Column1, Column2, Column3 ) VALUES ('John', 123, 'Lloyds Office'), ('Jane', 124, 'Lloyds Office'), ('Billy', 125, 'London Office'), ('Miranda', 126, 'Bristol Office');
- 一個事務提交:
開啟一個事務,批量操作完了才提交事務,而不是,操作一次就提交一次,這樣io太高,插入太慢。
- 插入欄位儘量少,儘量使用預設值:
注意事項: max_allowed_packet 預設是1M,如何insert values sql 太大需要上調這個值
order by 優化:
2中排序方式:
MySQL支援兩種方式的排序filesort和index,Using index是指MySQL掃描索引本身完成排序。index效率高,filesort效率低。
使用 using index的2中情況:
order by滿足兩種情況會使用Using index:
- order by語句使用索引最左前列;
- where子句與order by子句,條件列組合滿足索引最左前列;
優化:
- 儘量在索引列上完成排序,遵循索引建立(索引建立的順序)時的最佳左字首法則;
- 如果order by的條件不在索引列上,就會產生Using filesort;
- 在使用order by時,不要用select *,只查詢所需的欄位:
因為當查詢欄位過多時,會導致sort_buffer不夠,從而使用多路排序或進行多次I/O操作
-
嘗試提高sort_buffer_size;
-
嘗試提高max_length_for_sort_data
基於using filesort的優化:
- filesort有兩種排序演算法:雙路排序和單路排序
- 雙路排序:
在MySQL4.1之前使用雙路排序,就是兩次磁碟掃描,得到最終資料。讀取行指標和order by列,對他們進行排序,然後掃描已經排好序的列表,按照列表中的值重新從列表中讀取對應的資料輸出。
即從磁碟讀取排序欄位,在buffer進行排序,再從磁碟取其他欄位。 - 單路排序:
從磁碟中查詢所需的列,按照order by列在buffer中對它們進行排序,然後掃描排序後的列表進行輸出。它的效率更高一些,避免了第二次讀取資料,並且把隨機I/O變成了順序I/O,但是會使用更多的空間,因為它把每一行都儲存在記憶體中了。
- 雙路排序:
- 單路排序的問題:
當讀取資料超過sort_buffer的容量時,就會導致多次讀取資料,並建立臨時表,最後多路合併,產生多次I/O,反而增加其I/O運算。
- 解決辦法:
- 增加sort_buffer_size引數的設定。
- 增大max_length_for_sort_data引數的設定。
- 解決辦法: