數據庫索引

索引定義
數據庫索引比如書的目錄,對數據庫表中一個或多個字段的值進行排序的結構。在查找索引字段中保存的某個值的時候經過查「目錄」會比逐條地查找數據記錄快不少。索引也是一種表,存儲着索引字段和指向實際表記錄的指針。
索引的利弊
-- 利html

1.大大加快數據的檢索速度;   
2.建立惟一性索引,保證數據庫表中每一行數據的惟一性;   
3.加速表和表之間的鏈接;   
4.在使用分組和排序子句進行數據檢索時,能夠顯著減小查詢中分組和排序的時間。

-- 弊mysql

1.索引須要佔用數據表之外的物理存儲空間;
2.更新數據表數據記錄時,也須要更新相應的索引,所以會下降數據表的更新速度;   

索引類型
-- 按功能邏輯劃分爲如下4類:
normal:普通索引
unique:不容許重複的索引
fulltextl:全文索引,只能夠在VARCHAR或者TEXT類型的列上建立。
spatial:空間索引(不經常使用)
全文檢索的對象是一個單詞,被檢索的詞須要用非文本隔開,而like模糊查詢的對象是字符
-- 按實現方式分:
Btree二叉樹、hash、Rtree
btree索引和hash索引的區別
-- hashsql

  1. 設置了hash索引的字段在範圍查詢和排序時索引失效,通過Hash運算後字段值的大小關係會發生變化,因此經過hash索引只能判斷字段值是否相等沒法比較大小;
  2. 設置多列索引的hash索引在查詢中只用到部分字段時索引失效,由於多個字段的組合索引的hash索引是將多個字段值組合到一塊兒計算hash值;
  3. 沒法避免表掃描,由於同一hash值可能對應多條記錄,因此經過hash索引只是縮小了查找範圍,但依然須要比較實際數據來查找最終匹配的記錄;
  4. 檢索效率高,但某些狀況下檢索效率會低於btree索引,由於hash索引能夠一次定位,不須要像樹形索引那樣逐層查找,可是若是有大量記錄對應同一hash值則會進行大範圍的表掃描形成效率低下;
  5. 只有Memory、NDB引擎支持hash,innodb並不顯式地支持hash,因此使用innodb引擎的表沒法手動設置hash索引;

-- btree數據庫

  1. 支持使用 =, >, >=, <, <=、BETWEEN、like 'key%' 運算符。

幾種致使索引失效的狀況函數

  1. 索引列參與計算;
  2. where子句中對索引字段使用了函數;
  3. 與非索引列進行or運算;
  4. 使用了Like %XXX;
  5. 字符串索引列與數字直接比較;
  6. 若是 MySQL 估計使用索引比全表掃描更慢,則不使用索引
  7. 設置了hash索引的字段在範圍查詢和排序時索引失效
  8. 設置多列索引的hash索引在查詢中只用到部分字段時索引失效
  9. 對索引字段使用 NOT IN 、<>、!=

固然也有一些變通方法,好比or能夠經過子集union的方式代替解決;like能夠藉助字符串反轉函數將%移到後面;字符串問題能夠將數字加引號轉爲字符串
索引策略大數據

  • 選擇在where子句中或在join子句中出現的列做爲索引列
  • 索引要創建在值比較惟一的字段上
  • 使用短索引
  • 儘可能避免容許爲null的字段上創建索引

建索引的幾大原則 引用自 https://tech.meituan.com/mysq...
1.最左前綴匹配原則,很是重要的原則,mysql會一直向右匹配直到遇到範圍查詢(>、<、between、like)就中止匹配,好比a = 1 and b = 2 and c > 3 and d = 4 若是創建(a,b,c,d)順序的索引,d是用不到索引的,若是創建(a,b,d,c)的索引則均可以用到,a,b,d的順序能夠任意調整。
2.=和in能夠亂序,好比a = 1 and b = 2 and c = 3 創建(a,b,c)索引能夠任意順序,mysql的查詢優化器會幫你優化成索引能夠識別的形式
3.儘可能選擇區分度高的列做爲索引,區分度的公式是count(distinct col)/count(*),表示字段不重複的比例,比例越大咱們掃描的記錄數越少,惟一鍵的區分度是1,而一些狀態、性別字段可能在大數據面前區分度就是0,那可能有人會問,這個比例有什麼經驗值嗎?使用場景不一樣,這個值也很難肯定,通常須要join的字段咱們都要求是0.1以上,即平均1條掃描10條記錄
4.索引列不能參與計算,保持列「乾淨」,好比from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,緣由很簡單,b+樹中存的都是數據表中的字段值,但進行檢索時,須要把全部元素都應用函數才能比較,顯然成本太大。因此語句應該寫成create_time = unix_timestamp(’2014-05-29’);
5.儘可能的擴展索引,不要新建索引。好比表中已經有a的索引,如今要加(a,b)的索引,那麼只須要修改原來的索引便可
查詢優化神器 - explain命令
關於explain命令相信你們並不陌生,具體用法和字段含義能夠參考官網explain-output,這裏須要強調rows是核心指標,絕大部分rows小的語句執行必定很快(有例外,下面會講到)。因此優化語句基本上都是在優化rows。
慢查詢優化基本步驟
0.先運行看看是否真的很慢,注意設置SQL_NO_CACHE
1.where條件單表查,鎖定最小返回記錄表。這句話的意思是把查詢語句的where都應用到表中返回的記錄數最小的表開始查起,單表每一個字段分別查詢,看哪一個字段的區分度最高
2.explain查看執行計劃,是否與1預期一致(從鎖定記錄較少的表開始查詢)
3.order by limit 形式的sql語句讓排序的表優先查
4.瞭解業務方使用場景
5.加索引時參照建索引的幾大原則
6.觀察結果,不符合預期繼續從0分析優化

相關文章
相關標籤/搜索