記一次SQL調優

insert優化

若是你在某一時刻有大量的insert操做,一條一條插入是很是耗時的。insert語句自己支持一次插入不少條記錄,插入記錄數上限受sql語句長度限制,通常一次插個幾千條是沒問題的。在個人 《如何手動實現Try Insert和Insert Or Update》 一文中對於各類狀況都有具體的例子,這裏就不贅述了。html

explain語句結果分析

SQL自己是一種對機器來講抽象級別很高的語言,咱們經過SQL告訴DBMS咱們須要什麼,而沒有告訴它具體要怎麼作。DBMS會猜想性地以最優的方法去完成咱們給的任務,可是它每每作得不太好,畢竟不一樣業務最優作法各不相同,目前咱們尚未辦法讓機器徹底理解咱們的業務。因此咱們須要輔助機器,幫助它找到最好的查詢邏輯。一般的作法是添加合適的索引,讓全部的查詢都走索引。在MySQL中,在任何一個select語句前加上explain,就能夠知道MySQL對這條查詢的理解和實際執行邏輯。mysql

下面來分析explain語句返回的結果。explain會展現查詢涉及到的每張表分析結果,裏面有不少參數,咱們通常只須要關注如下幾個參數:sql

  1. type優化

    type描述表是怎麼join的,按從最好到最壞一共有如下幾個值:code

    解釋
    system 表只有一行,是一種特殊的const type
    const 表裏只有一行匹配的記錄,join時能夠認爲是常量
    eq_ref 使用的索引爲primary keyunique not null index
    ref join只使用最左前綴匹配原則的普通索引
    fulltext 使用全文檢索索引
    ref_or_null ref差很少,主要是多了NULL值的查詢
    index_merge 使用了MySQL的索引合併優化
    unique_subquery 相似eq_ref,主要用於包含IN子查詢的查詢
    range 走索引的範圍查詢
    index 索引樹被整個掃了,速度比掃表好一點
    ALL 整個表被掃,很是糟糕的狀況,通常要避免

    通常作SQL優化,一般出現indexALL都是須要優化的。htm

  2. Extra對象

    MySQL查詢的附件信息,有時候表明着查詢的額外代價,出現 Using filesortUsing temperary都表示查詢速度不行。blog

    • Using filesort表示order by子句不走索引,使用文件排序,須要對order by進行優化。
    • Using temperary表示查詢過程當中建立了臨時表,一般發生在包含group byorder by的查詢中。
  3. rows和filtered排序

    rows表示MySQL預估的查詢須要的行數,filtered表示根據條件過濾以後的行所佔的百分比。值爲100表示沒有行被過濾掉。因此rows*filtered查詢須要的總的行數。這個值天然是越小越好。索引

查詢優化實踐

查詢優化的策略就是加索引,primary key 和 unique key在根據具體業務定,咱們作優化,通常都是添加普通索引。普通索引分爲兩種,單個字段的索引和多個字段的聯合索引。聯合索引的應用場景相對窄一點,若是你要查的數據能夠被聯合索引所有囊括,直接從索引拿數據,能夠考慮使用聯合索引。讀多寫少重複值少散列分佈的字段最適合建索引。你能夠把你的程序使用到的全部SQL都列出來,一條一條explain,沒有走索引的,就酌情給某個或某幾個字段(join裏的字段、where裏的字段都是重點考慮對象)加上索引,直到全部的查詢走索引爲止。這麼作之後,你的查詢type正常均可以到達比較好的狀況,可是對於包含order by子句的查詢,可能你的Extra信息就不太理想了。Using filesortUsing temperary有時候陰魂不散,很難搞。這時候最佳的策略就是變着花樣選擇排序的字段。好比你的表有一個自增主鍵,你能夠考慮用它做爲插入時間來作排序。MySQL自己在這方面的優化很是糟糕,須要耐心地多嘗試。

Reference

MySQL explain

MySQL ORDER BY優化

相關文章
相關標籤/搜索