索引mysql
什麼是索引?sql
索引在MySQL中也叫作「鍵」,是存儲引擎用於快速找到記錄的一種數據結構數據結構
爲什麼使用索引?測試
加快查詢速度大數據
索引的本質?優化
經過不斷地縮小想要獲取數據的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,咱們能夠老是用同一種查找方式來鎖定數據。blog
索引的數據結構?排序
b+樹應運而生(B+樹是經過二叉查找樹,再由平衡二叉樹,B樹演化而來)。索引
b+樹性質事件
1.索引字段要儘可能的小,緣由:使用大數量項會使磁盤塊可存儲數據數量變少,從而增高b+樹的高度,使io次數變多
2. 索引的最左匹配特性
彙集索引與輔助索引
相同:不論是彙集索引仍是輔助索引,其內部都是B+樹的形式,即高度是平衡的,葉子結點存放着全部的數據。
不一樣:葉子結點存放的是不是一整行的信息
彙集索引
若是未定義主鍵,MySQL取第一個惟一索引(unique)並且只含非空列(NOT NULL)做爲主鍵,InnoDB使用它做爲聚簇索引。
若是沒有這樣的列,InnoDB就本身產生一個這樣的ID值,它有六個字節,並且是隱藏的,使其做爲聚簇索引。
因爲實際的數據頁只能按照一棵B+樹進行排序,所以每張表只能擁有一個彙集索引。在多少狀況下,查詢優化器傾向於採用彙集索引。由於彙集索引可以在B+樹索引的葉子節點上直接找到數據。此外因爲定義了數據的邏輯順序,彙集索引可以特別快地訪問針對範圍值得查詢。
好處:
1.它對主鍵的排序查找和範圍查找速度很是快,葉子節點的數據就是用戶所要查詢的數據。如用戶須要查找一張表,查詢最後的10位用戶信息,因爲B+樹索引是雙向鏈表,因此用戶能夠快速找到最後一個數據頁,並取出10條記錄
2. 範圍查詢(range query),即若是要查找主鍵某一範圍內的數據,經過葉子節點的上層中間節點就能夠獲得頁的範圍,以後直接讀取數據頁便可
輔助索引
表中除了彙集索引外其餘索引都是輔助索引(Secondary Index,也稱爲非彙集索引),與彙集索引的區別是:輔助索引的葉子節點不包含行記錄的所有數據。
葉子節點除了包含鍵值之外,每一個葉子節點中的索引行中還包含一個書籤(bookmark)。該書籤用來告訴InnoDB存儲引擎去哪裏能夠找到與索引相對應的行數據。
索引管理
聯合索引:
-PRIMARY KEY(id,name):聯合主鍵索引
-UNIQUE(id,name):聯合惟一索引
-INDEX(id,name):聯合普通索引
建立,新增索引方式:
#方式一
create table t1(
id int,
name char,
age int,
sex enum('male','female'),
unique key uni_id(id),
index ix_name(name) #index沒有key
);
#方式二
create index ix_age on t1(age);
#方式三
alter table t1 add index ix_sex(sex);
測試索引
1. 必定是爲搜索條件的字段建立索引,好比select * from s1 where id = 333;就須要爲id加上索引
2.在表中已經有大量數據的狀況下,建索引會很慢,且佔用硬盤空間,建完後查詢速度加快
3. 須要注意的是:innodb表的索引會存放於s1.ibd文件中,而myisam表的索引則會有單獨的索引文件table1.MYI
正確使用索引
1 範圍問題,或者說條件不明確,條件中出現這些符號或關鍵字:>、>=、<、<=、!= 、between...and...、like(使用%開頭時)
2 儘可能選擇區分度高的列做爲索引,區分度的公式是count(distinct col)/count(*),表示字段不重複的比例,比例越大咱們掃描的記錄數越少,惟一鍵的區分度是1,而一些狀態、性別字段可能在大數據面前區分度就是0,那可能有人會問,這個比例有什麼經驗值嗎?使用場景不一樣,這個值也很難肯定,通常須要join的字段咱們都要求是0.1以上,即平均1條掃描10條記錄
3 =和in能夠亂序,好比a = 1 and b = 2 and c = 3 創建(a,b,c)索引能夠任意順序,mysql的查詢優化器會幫你優化成索引能夠識別的形式
4 索引列不能參與計算
5 and/or
6最左前綴匹配原則
注意事項:
- 避免使用select *
- count(1)或count(列) 代替 count(*)
- 建立表時儘可能時 varchar 代替 char
- 表的字段順序固定長度的字段優先
- 組合索引代替多個單列索引(常用多個條件查詢時)
- 儘可能使用短索引
- 使用鏈接(JOIN)來代替子查詢(Sub-Queries)
- 連表時注意條件類型需一致
- 索引散列值(重複少)不適合建索引,例:性別不適合
聯合索引
Create index inx_xxx on s1(email,name,gender,id);
覆蓋索引
InnoDB存儲引擎支持覆蓋索引(covering index,或稱索引覆蓋),即從輔助索引中就能夠獲得查詢記錄,而不須要查詢彙集索引中的記錄。
查詢優化神器-explain
explain select * from userinfo3 where name='alex'