mysql索引優化

mysql 大數據分頁和索引使用

使用覆蓋索引

  1. 一個表創建在id,create_time上創建了索引。
  2. 以下2個sql語句,執行時間同樣。 由於查詢字段id被索引覆蓋。mysql

    select id from order_manage where  create_time > '2014-01-01'
     order by create_time desc  limit 100000,10
    
    
     select a.id from order_manage a
     inner join ( select id from order_manage 
     where  create_time > '2014-01-01' 
     order by create_time desc limit 1000,10) b on a.id = b.id
  3. 以下2條sql,使用inner join要快一個數量級。 inner join影響結果集仍然是$start +30,可是數據獲取的過程(Sending data狀態)發生在索引文件中,而不是數據表文件,這樣所須要的系統開銷就比前一種普通的查詢低一個數量級,而主查詢的影響結果集只有30條,幾乎無開銷。可是切記,這裏仍然涉及了太多的影響結果集操做sql

    其實也能夠分紅2條sql語句來作,第一條使用覆蓋索引查詢出id,在使用in查詢出須要的字段數據。數據結構

    select * from order_manage where  create_time > '2014-01-01'
     order by create_time desc  limit 100000,10
    
    
     select * from order_manage a
     inner join ( select id from order_manage 
     where  create_time > '2014-01-01' 
     order by create_time desc limit 1000,10) b on a.id = b.id

上一頁,下一頁優化

  1. 背景,常見論壇帖子頁 SQL: select * from post where tagid=$tagid order by lastpost limit $start, $end 翻頁 。索引爲 tagid+lastpost 複合索引
    挑戰, 超級熱帖,幾萬回帖,用戶頻頻翻到末頁,limit 25770,30 一個操做下來,影響結果集巨大(25770+30),查詢緩慢。
  2. 每次查詢的時候將該頁查詢結果中最大的 $lastpost和最小的分別記錄爲 $minlastpost 和 $maxlastpostpost

    上翻頁查詢爲 
     select * from post where tagid=$tagid and lastpost<$minlastpost order by lastpost desc limit 30; 
     下翻頁爲 
     select * from post where tagid=$tagid and lastpost>$maxlastpost order by lastpost limit 30;
     使用這種方式,影響結果集只有30條,效率極大提高。

order by排序優化

  1. 以下sql :大數據

    select * from user where area=’$area’ and sex=’$sex’ order by lastlogin desc limit 0,30;

    創建複合索引並, area+sex+lastlogin 三個字段的複合索引(注意順序),order by的字段要在最後。where條件字段,惟一性最好的要在最前。優化

    Area+sex+lastlogin複合索引時(切記lastlogin在最後),該索引基於area+sex+lastlogin 三個字段合併的結果排序。
    也就是說,創建了複合索引,少了一次排序操做。
  2. 牢記數據查詢只能使用一個索引,每一個字段創建獨立索引的狀況下,也只能有一條索引被使用!
  3. 複合索引的使用是符合左邊原則。a,b,c的複合索引
    abc,ab,a,可使用索引,其餘狀況都不能使用索引。
    複合索引的使用原則是第一個條件應該是複合索引的第一列必須使用,而且不能誇列。ac是不能使用索引的。code

msyql索引使用原則

  1. 牢記數據查詢只能使用一個索引,每一個字段創建獨立索引的狀況下,也只能有一條索引被使用!msyql會選擇最優化的索引。固然你能夠強制使用索引,不過不建議這麼作。
  2. 在進行索引分析和SQL優化時,能夠將數據索引字段想象爲單一有序序列,並以此做爲分析的基礎。涉及到複合索引狀況,複合索引按照索引順序拼湊成一個字段,想象爲單一有序序列,並以此做爲分析的基礎。
  3. 查詢條件與索引的關係決定影響結果集
    • 影響結果集不是輸出結果數,不是查詢返回的記錄數,而是索引所掃描的結果數。
    • 影響結果集越趨近於實際輸出或操做的目標結果集,索引效率越高
    • 影響結果集與查詢開銷的關係能夠理解爲線性相關。減小一半影響結果集,便可提高一倍查詢效率!當一條搜索query能夠符合多個索引時,選擇影響結果集最少的索引。
    • SQL的優化,核心就是對結果集的優化,認識索引是加強對結果集的判斷,基於索引的認識,能夠在編寫SQL的時候,對該SQL可能的影響結果集有預判,並作出適當的優化和調整。
    • 若是索引與查詢條件和排序條件徹底命中,影響結果集就是limit後面的數字($start + $end),好比 limit 200,30 影響結果集是230. 而不是30.
    • 若是索引只命中部分查詢條件,甚至無命中條件,在無排序條件狀況下,會在索引命中的結果集 中遍歷到知足全部其餘條件爲止。好比 select * from user limit 10; 雖然沒用到索引,可是由於不涉及二次篩選和排序,系統直接返回前10條結果,影響結果集依然只有10條,就不存在效率影響
    • 若是搜索所包含的排序條件沒有被索引命中,則系統會遍歷是全部索引所命中的結果,而且排序。例如 Select * from user order by timeline desc limit 10; 若是timeline不是索引,影響結果集是全表,就存在須要全表數據排序,這個效率影響就巨大。再好比 Select * from user where area=’廈門’ order by timeline desc limit 10; 若是area是索引,而area+timeline未創建索引,則影響結果集是全部命中 area=’廈門’的用戶,而後在影響結果集內排序。
  4. 基於影響結果集的理解去優化,不論從數據結構,代碼,仍是涉及產品策略上,都須要貫徹下去。核心就是小表驅動大表,索引的使用要篩選出最少的結果集。
  5. 涉及 limit $start,$num的搜索,若是$start巨大,則影響結果集巨大,搜索效率會很是難太低,儘可能用其餘方式改寫爲 limit 0,$num; 確係沒法改寫的狀況下,先從索引結構中得到 limit $start,$num 或limit $start,1 ;再用in操做或基於索引序的 limit 0,$num 二次搜索。
  6. 外鍵和join儘可能不用
相關文章
相關標籤/搜索