MySQL 中創(chuàng)建索引的語句和 explain
索引為什么使用B+樹,而不是B樹
存儲方式
數(shù)據(jù)庫中是按照塊進行存儲,在計算機的世界中,所有的與空間相關的內(nèi)容全部是按照塊進行存儲和使用的,只是塊的大小劃分不同而已。
例如:文件系統(tǒng)中,即硬盤中,每塊的大小是4K;在計算機內(nèi)存中,按照32位一個塊就行存儲的。
塊大的優(yōu)點:
相對于小塊存儲,塊大后一次可以存儲和取出更多的數(shù)據(jù),這樣就降低了存取的次數(shù);
缺點:
會浪費更多的計算機儲存空間;例如一個文件只有3K,但也必須為其開辟一個4K大小的存儲空間。
使用B+樹的原因
- B-樹的存儲,數(shù)據(jù)和索引在一起,每條數(shù)據(jù)和索引同時占有塊的存儲空間,B-樹階數(shù)越高,需要查詢的塊數(shù)就越多;
- 如果使用B+樹,由于B+樹的性質,數(shù)據(jù)都存在葉子節(jié)點,而根節(jié)點或父節(jié)點存儲的是索引,如此一來,可以將上面的索引單獨存儲起來,葉子節(jié)點的數(shù)據(jù)單獨存儲起來,由于索引占用的空間比實際數(shù)據(jù)小很多,所以存儲索引所用的塊會比較少,這樣在查詢較深的數(shù)據(jù)時也不會查詢太多的塊。
隨機I/O和順序I/O
即相當于硬盤中隨機讀寫和順序讀寫;其時間倍數(shù)約為 隨機讀寫 * 1000 = 順序讀寫
如果樹的每一層都是順序存儲,每層間進行查找都屬于隨機I/O,如此一來,B-樹在查找數(shù)據(jù)時,根據(jù)中序遍歷的規(guī)則,B-樹會進行多次的隨機I/O,而B+樹相對一次查詢來說,次數(shù)會少很多次,從而提高了查詢速度。
B+Tree
正常情況下,如果不指定索引的類型,那么一般是指B+Tree索引(或者B+Tree索引)。存儲引擎以不同的方式使用B+Tree索引。性能也各有不同,但是InnoDB按照原數(shù)據(jù)格式進行存儲。
B+Tree 索引能夠加快數(shù)據(jù)的讀取速度,因為存儲引擎不再需要進行全表掃描來獲取需要的數(shù)據(jù),相反是從索引的根節(jié)點開始進行搜索,通過相應的指針移動,最終存儲引擎要么找到了對應的值,要么該記錄不存在。樹的深度與表的大小直接相關。
B+Tree索引是按照順序組織存儲的,所以適合范圍查找數(shù)據(jù)
B+Tree索引使用與全鍵值、鍵值范圍或者鍵前綴查找,其中鍵前綴進適用于根據(jù)最左前綴的查找。
a、 全值匹配
b、 匹配最左前綴。
c、 匹配列前綴。
d、 匹配范圍值
e、 精確匹配某一列并范圍匹配另外一列。
f、 只訪問索引的查詢(覆蓋索引)
B-Tree索引的限制:
a、 如果不是按照索引的最左列開始查找,那么無法使用索引
b、 不能跳過索引中的某些列。
c、 如果查詢中使用了某個列的范圍查詢,那么該列右邊的所有列都無法使用索引。
MySQL 中 B+樹索引的兩種類型
聚集索引
聚集索引是指數(shù)據(jù)庫表行中數(shù)據(jù)的物理順序與鍵值的邏輯(索引)順序相同;索引之下的一個葉子節(jié)點就是一條數(shù)據(jù)。
MySQL中聚集索引只有一個,就是主鍵。
非聚集索引
非聚集索引是一種索引,該索引中索引的邏輯順序與磁盤上行的物理存儲順序不同。;索引之下的葉子節(jié)點指向的是主鍵而不是數(shù)據(jù)。
MySQL中除了主鍵以外的索引為非聚集索引。
MySQL中多個列的索引
多個索引就相當于B+樹上的節(jié)點的每個數(shù)據(jù)是一個元組形式
主鍵
主鍵為聚集索引,主鍵不能為空。
唯一鍵
如果唯一鍵和主鍵同時存在,則唯一鍵為非聚集索引;如果主鍵不存在,則唯一索引為聚集索引。
唯一鍵可以為空,這是它與主鍵的區(qū)別所在。
創(chuàng)建語句
create unique index index_name on tabl_name (列名1[,列名2])
普通索引
普通索引為非聚集索引,普通索引無限制。
創(chuàng)建語句
create index index_name on table_name(列名1[,列名2])
explain 執(zhí)行計劃
explain 指的是某個sql語句的執(zhí)行計劃:explain sql語句
id: 1
select_type: SIMPLE(簡單查詢,不是多表查詢和復雜查詢) 可能的值:simple,primary,union,dependent union,union result
table: php114(表名)
type: ALL() 可能的值:system,const(最優(yōu)化,使用了主鍵或者唯一健),eq_ref,ref.ref_or_null,index_merge
possible_keys: NULL 提示使用哪個索引會在該表中找到行
key: NULL() mysql使用的索引,簡單且重要
key_len: NULL() mysql使用的索引長度
ref: NULL 顯示使用哪個列或者常數(shù)與key一起從表中選擇行
rows: 6 mysql執(zhí)行查詢的行數(shù),簡單且重要,數(shù)值越大越不好,說明沒有用好索引
Extra: 包含mysql解決查詢的詳細信息