MySQL筆記(4)-- 索引優化

  • 索引失效狀況:
    • 最佳左前綴法則:若是索引了多列,要遵循最左前綴法則,指的是查詢從索引的最左前列開始而且不跳過索引中的列;【覆蓋索引有a,b,c,條件中使用了b或bc都致使該索引失效;若是條件使用了ac,致使部分索引生效,只使用了a】【索引開頭第一個不能去掉,中間部分不能斷】
    • 不在索引列上作任何操做(計算、函數、(自動或手動)類型轉換),會致使索引失效而進行全表掃描;【where條件的字段不作任何操做,不然致使索引失效】
    • 存儲引擎不能使用索引中範圍條件右邊的列;【覆蓋索引有a,b,c,a是常量,b是範圍,致使索引用到了a,b,後面的c失效】
    • 儘可能使用覆蓋索引(只訪問索引的查詢(索引列和查詢列一致)),減小select *;

    • MySQL在使用不等於(!=或<>)的時候沒法使用索引會致使全表掃描;
    • is null和is not null沒法使用索引;
    • like以通配符開頭('%abc...'或'%abc'),MySQL索引失效致使全表掃描;【'abc...%'不會致使索引失效】【解決方法:使用覆蓋索引來解決,即對select的字段建立索引】【id是主鍵,默認建立索引】

      下面的SQL索引失效【使用*或多了字段】:mysql

    • 字符串不加單引號致使索引失效;【例如name是varchar類型,條件where name=1作了隱形類型轉換,還會致使索引失效,下降MySQL性能】
    • 少用or,用它來鏈接會致使索引失效;
    • 總結:
  • 查詢優化:
    •  小表驅動大表:小的數據集驅動大的數據集sql

      1.當B表的數據集必須小於A表的數據集時,用in優於exists
      select * from A where id in (select id from B)
      等價 
      for select id from B
      for select *from A where A.id=B.id
      2.當A表的數據集小於B表的數據集時,用exists優於in
      select *from A where exists (select 1 from B where B.id=A.id);
      等價
      for select *from A
      for select *from B where B.id=A.id

 

      • exists:select ...from table where exists(subquery) 將主查詢的數據,放到子查詢中作條件判斷,根據驗證結果true或false來決定主查詢的數據結果是否能夠保留;
        • exists(subquery)只返回true或false,所以子查詢中的select *能夠是select 1或其餘,由於在實際執行時會忽略select清單;
        • exists子查詢能夠用條件表達式、其餘子查詢或join;
    • order by關鍵字優化:文件排序、掃描有序索引排序兩種方式;
      創建索引:key abc(a,b,c)
      order by使用索引最左前綴原則:(有序索引排序,using index)
      --order by a
      --order by a,b
      --order by a,b,c
      --order by a desc,b desc,c desc(升降序一致)
      若是where使用索引的最左前綴定義爲常量,則使用索引且是有序索引排序(using index):
      --where a=const order by b,c
      --where a=const and b=const order by c
      --where a=const and b>const order by b,c
      產生文件排序(using filesort):
      --order by b(非最左前綴)
      --order by b,a(順序顛倒)
      --order by a asc,b desc,c desc (排序不一致)
      --where d=const order by b,c (a丟失)
      --where a=const order by c(b丟失)
      --where a=const order by a,d(d不是索引的一部分)
      --where a in(..) order by b,c(範圍查詢)
    • group by關鍵字優化:group by實質是先排序後進行分組,遵守索引的最左前綴原則;當沒法使用索引列時,增大max_length_for_sort_data參數的設置和增大sort_buffer_size參數的設置;where高於having,能寫在where限定的條件就不要去having限定;
  • 慢查詢日誌的配置:
    在my.cnf文件中[mysqld]增長或修改參數:
    slow_query_log=1
    slow_query_log_file=/文件存儲路徑/fileName.log【若沒有指定,系統默認給一個指定的文件host_name-slow.log】查看達到寫入慢查詢日誌的閥值:SHOW VARIABLES LIKE 'long_query_time%';【默認狀況下爲10秒,即查詢時間大於10秒的sql會記錄到日誌中】設置閥值:set global long_query_time=數值;【設置結束後須要新開一個會話或從新鏈接纔看見修改信息,或使用show global variables like 'long_query_time'查看】查看當前系統的慢查詢SQL總條數:show global status like '%Slow_queries%';
相關文章
相關標籤/搜索