關於mysql 索引自動優化機制: 索引選擇性(Cardinality:索引基數)

一、兩個一樣結構的語句一個沒有用到索引的問題:

查1到20號的就不用索引,查1到5號的就用索引,爲何呢?不穩定?
 
mysql> explain select * from test where f_submit_time between '2009-09-01' and '2009-09-20' \G; 
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
         type: ALL
possible_keys: PRIMARY,submit_time_index
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 365628
        Extra: Using where
1 row in set (0.02 sec)
 
 
mysql> explain select * from test where f_submit_time between '2009-09-01' and '2009-09-5' \G;  
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
         type: range
possible_keys: PRIMARY,submit_time_index
          key: submit_time_index
      key_len: 8
          ref: NULL
         rows: 52073
        Extra: Using where
1 row in set (0.00 sec)
 
 
說明:
二叉樹索引原本最適合的就是點查詢,和小範圍的range查詢,
當預估返回的數據量超過必定比例( 貌似當預估的查詢量達到總量的30% )的時候,
再根據索引一條一條去查就慢了,反而不如全表掃描快了。Mysql有本身內部自動優化機制,
但有些自動優化機制可能不是最優的。這時候就須要人工去幹預。
好比長期不優化表,Mysql判斷出索引不優,就會不使用索引。
有時候就要人工強制使用真正高效的索引(FORCE INDEX)。
 

其實當自己的查詢就約等於一個全表查詢的時候,強不強制使用索引基本上沒什麼效果。mysql

二、再看個例子:

    今天遇到一個奇怪的問題,明明已經創建了索引,select語句的explain也代表會利用這個索引,但是結果恰恰沒有用索引,最後掃描了全表。
    兩個結構徹底同樣的sql語句:sql

     sql1: select * from table where col_a = 123 and col_b in (‘foo’,\'bar’) order by id desc;

    sql2: select * from table where col_a = 456 and col_b in (‘foo’,\'bar’) order by id desc;

    結果sql1選擇利用了col_a的索引,速度很快,sql2利用了主鍵ID的索引,掃描了全表(40w行)。
    仔細分析,發現數據庫中,col_a=456的記錄數有近1萬條,而col_a=123的記錄數只有幾條。
    因而就清楚了,MySQL選擇索引不單單依據查詢結構和索引結構,還會根據索引大概估算選擇每種索引的數據量,而後選擇他認爲最快的索引。
    多是主鍵索引會比普通index更快,因此mysql最後選擇了數據量跟大的id索引。
    那麼,如何解決這個問題呢?
     很簡單,只要在order語句裏寫多個鍵便可,好比:order by col_a, id desc數據庫

REF:mysql查詢中利用索引的機制  http://blogread.cn/it/article/5023?f=wb性能

三、本質緣由:Cardinality(索引基數)

很關鍵的一個參數,平均數值組=索引基數/表總數據行,平均數值組越接近1就越有可能利用索引。mysql索引

索引選擇性是不重複的索引值也叫基數(cardinality)表中數據行數的比值,索引選擇性=基數/數據行,基數能夠經過「show index from 表名」查看。   
高索引選擇性的好處就是mysql查找匹配的時候能夠過濾更多的行,惟一索引的選擇性最佳,值爲1。優化

四、關於 mysql 索引優化與使用請見:

由淺入深探究mysql索引結構原理、性能分析與優化.net

相關文章
相關標籤/搜索