1. 程式人生 > 實用技巧 >mysql - SQL 優化小結

mysql - SQL 優化小結

優化批量插入資料:

  1. 資料來源,根據主鍵做好排序,再進行資料匯入:
    mysql> load data local infile '/root/sql1.log' intotable `table_1` fields terminated by ',' lines terminated by '\n';

  2. 關閉唯一性校驗:
    在匯入資料前執行SET UNIQUE_CHECKS=0,關閉唯一性校驗,在匯入結束後執行SET UNIQUE_CHECKS=1,恢復唯一性校驗,可以提高匯入的效率。

  3. 手動提交:
    如果應用使用自動提交的方式,建議在匯入前執行SET AUTOCOMMIT=0,關閉自動提交,匯入結束後再執行SET AUTOCOMMIT=
    1,開啟自動提交,也可以提高匯入的效率。

insert語句優化:

  1. values多個:
    INSERT INTO MyTable
      ( Column1, Column2, Column3 )
    VALUES
      ('John', 123, 'Lloyds Office'), 
      ('Jane', 124, 'Lloyds Office'), 
      ('Billy', 125, 'London Office'),
      ('Miranda', 126, 'Bristol Office');

  2. 一個事務提交:
    開啟一個事務,批量操作完了才提交事務,而不是,操作一次就提交一次,這樣io太高,插入太慢。

  3. 插入欄位儘量少,儘量使用預設值:
    注意事項: max_allowed_packet 預設是1M,如何insert values sql 太大需要上調這個值

order by 優化:

2中排序方式:

MySQL支援兩種方式的排序filesortindex,Using index是指MySQL掃描索引本身完成排序。index效率高,filesort效率低。

使用 using index的2中情況:

order by滿足兩種情況會使用Using index:

    1. order by語句使用索引最左前列
    2. where子句與order by子句,條件列組合滿足索引最左前列

優化:

  1. 儘量在索引列上完成排序,遵循索引建立(索引建立的順序)時的最佳左字首法則;
  2. 如果order by的條件不在索引列上,就會產生Using filesort
  3. 在使用order by時,不要用select *,只查詢所需的欄位:
    因為當查詢欄位過多時,會導致sort_buffer不夠,從而使用多路排序或進行多次I/O操作

  4. 嘗試提高sort_buffer_size;

  5. 嘗試提高max_length_for_sort_data

基於using filesort的優化:

  1. filesort有兩種排序演算法:雙路排序和單路排序
    1. 雙路排序:
      在MySQL4.1之前使用雙路排序,就是兩次磁碟掃描,得到最終資料。讀取行指標和order by列,對他們進行排序,然後掃描已經排好序的列表,按照列表中的值重新從列表中讀取對應的資料輸出。
      即從磁碟讀取排序欄位,在buffer進行排序,再從磁碟取其他欄位
    2. 單路排序:
      從磁碟中查詢所需的列,按照order by列在buffer中對它們進行排序,然後掃描排序後的列表進行輸出。它的效率更高一些,避免了第二次讀取資料,並且把隨機I/O變成了順序I/O,但是會使用更多的空間,因為它把每一行都儲存在記憶體中了。

  2. 單路排序的問題:
    當讀取資料超過sort_buffer的容量時,就會導致多次讀取資料,並建立臨時表,最後多路合併,產生多次I/O,反而增加其I/O運算。
    1. 解決辦法:
      1. 增加sort_buffer_size引數的設定。
      2. 增大max_length_for_sort_data引數的設定。