索引定義
數據庫索引比如書的目錄,對數據庫表中一個或多個字段的值進行排序的結構。在查找索引字段中保存的某個值的時候經過查「目錄」會比逐條地查找數據記錄快不少。索引也是一種表,存儲着索引字段和指向實際表記錄的指針。
索引的利弊
-- 利html
1.大大加快數據的檢索速度; 2.建立惟一性索引,保證數據庫表中每一行數據的惟一性; 3.加速表和表之間的鏈接; 4.在使用分組和排序子句進行數據檢索時,能夠顯著減小查詢中分組和排序的時間。
-- 弊mysql
1.索引須要佔用數據表之外的物理存儲空間; 2.更新數據表數據記錄時,也須要更新相應的索引,所以會下降數據表的更新速度;
索引類型
-- 按功能邏輯劃分爲如下4類:
normal:普通索引
unique:不容許重複的索引
fulltextl:全文索引,只能夠在VARCHAR或者TEXT類型的列上建立。
spatial:空間索引(不經常使用)
全文檢索的對象是一個單詞,被檢索的詞須要用非文本隔開,而like模糊查詢的對象是字符
-- 按實現方式分:
Btree二叉樹、hash、Rtree
btree索引和hash索引的區別
-- hashsql
-- btree數據庫
幾種致使索引失效的狀況函數
固然也有一些變通方法,好比or能夠經過子集union的方式代替解決;like能夠藉助字符串反轉函數將%移到後面;字符串問題能夠將數字加引號轉爲字符串
索引策略大數據
建索引的幾大原則 引用自 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分析優化