mysql -b -e_MySQL 的B+树索引.
一、B+樹索引概述
索引是應(yīng)用程序設(shè)計(jì)和開發(fā)的一個(gè)重要方面。若索引太多,應(yīng)用程序的性能可能會(huì)受到影響(需維護(hù)索引的結(jié)構(gòu)和數(shù)據(jù));而索引太少,對(duì)查詢性能又會(huì)產(chǎn)生影響。
二叉樹,左子樹的鍵值總是小于根的鍵值,右子樹的鍵值總是大于根的鍵值。
平衡二叉樹(AVL樹),任何節(jié)點(diǎn)的兩個(gè)子樹的高度最大差為 1。平衡二叉樹的查詢速度很快,但是維護(hù)一棵平衡二叉樹的代價(jià)是非常大的。通常來(lái)說(shuō),需要 1 次或多次左旋和右旋來(lái)得到插入或更新后樹的平衡性。
B+ 樹是為磁盤或其他直接存取輔助設(shè)備設(shè)計(jì)的一種平衡查找樹,B+ 樹中的 B 不是代表二叉(binary),而是代表平衡(balance)。在 B+ 樹中,所有記錄節(jié)點(diǎn)都是按鍵值的大小順序存放在同一層的葉子節(jié)點(diǎn)上,由各葉子節(jié)點(diǎn)指針進(jìn)行連接,葉子節(jié)點(diǎn)之間組成一個(gè)雙向鏈表。
B+ 樹索引的本質(zhì)就是 B+ 樹在數(shù)據(jù)庫(kù)中的實(shí)現(xiàn),但是 B+ 索引在數(shù)據(jù)庫(kù)中有一個(gè)特點(diǎn)是高扇出性(數(shù)據(jù)庫(kù)分區(qū)),因此在數(shù)據(jù)庫(kù)中,B+ 樹的高度一般都在 2-4 層,這也就是說(shuō)查找某一鍵值的行記錄時(shí)最多只需要 2 到 4 次IO。
數(shù)據(jù)庫(kù)中的 B+ 樹索引可以分為 聚集索引和輔助索引。
B+ 樹索引并不能找到一個(gè)給定鍵值的具體行。B+ 樹索引能找到的只是被查找數(shù)據(jù)行所在的頁(yè)。然后數(shù)據(jù)庫(kù)通過(guò)把頁(yè)讀入到內(nèi)存,再在內(nèi)存中查找,最后得到要查找的數(shù)據(jù)。
二、索引創(chuàng)建和查看
索引的創(chuàng)建和刪除可以通過(guò)兩種方法,一種是 ALTER TABLE,另一種是 CREATE/DROP INDEX。用戶可以設(shè)置對(duì)整個(gè)列的數(shù)據(jù)進(jìn)行索引,也可以只索引一個(gè)列的開頭部分?jǐn)?shù)據(jù)。
## 添加索引
alter table add index (column_list);
alter table add unique(column_list);
alter table add primary key(column_list);
## 刪除索引
alter table drop index ;
alter table drop primary key;
## 添加索引
create index on (column_list);
create unique index on (column_list);
## 刪除索引
drop index on ;
索引的查看,可以使用命令 SHOW INDEX。
SHOW INDEX FROM
Non_unique 表示是否非唯一的索引;Column_name 表示索引列的名稱;Seq_in_index 表示索引中該列的位置;Collation 表示列以什么方式存儲(chǔ)在索引中,可以是 A 或 NULL,B+ 樹索引總是 A,即排序的;Sub_part 是否是列的部分被索引,如果是整個(gè)列,則該字段顯示為 NULL;Packed 關(guān)鍵字如何被壓縮;Null 是否索引中的列含有 NULL 值;Index_type 索引的類型。
Cardinality 非常關(guān)鍵的值,表示索引中唯一值的數(shù)目的估計(jì)值,優(yōu)化器會(huì)根據(jù)這個(gè)值來(lái)判斷是否使用這個(gè)索引。這個(gè)值并不是實(shí)時(shí)更新的,如果需要實(shí)時(shí)更新 Cardinality 的信息,可以使用 ANALYZE TABLE 命令。建議在非高峰時(shí)間,對(duì)應(yīng)用程序下的幾張核心表做 ANALYZE TABLE 操作,這能使優(yōu)化器和索引更好的工作(除了 ANALYZE TABLE 外,還有 SHOW TABLE STATUS、SHOW INDEX 以及訪問(wèn) INFORMATION SCHEMA 架構(gòu)下的表 TABLES 和 STATISTICS 都會(huì)去重新計(jì)算 Cardinality 值)。
MySQL 對(duì)于主鍵索引的創(chuàng)建會(huì)采用臨時(shí)表的方式,首先會(huì)創(chuàng)建一張帶有主鍵索引的臨時(shí)表,然后把原表中數(shù)據(jù)導(dǎo)入到臨時(shí)表,接著刪除原表,最好把臨時(shí)表重命名為原表名,這部分操作會(huì)導(dǎo)致數(shù)據(jù)庫(kù)不可用,因此建議在創(chuàng)建表的時(shí)候就定義好主鍵!
MySQL 對(duì)于輔助索引的創(chuàng)建支持 FIC —— Fast Index Creation(快速索引創(chuàng)建)方式,其會(huì)對(duì)創(chuàng)建索引的表加上一個(gè) S 鎖,不需要建立臨時(shí)表。
MySQL 5.6 版本開始支持 Online DDL(在線數(shù)據(jù)定義)操作,其允許輔助索引創(chuàng)建的同時(shí),還允許其他諸如 INSERT、UPDATE、DELETE 這類 DML 操作,其原理是將 DML 操作日志寫入到一個(gè)緩存中,待完成索引創(chuàng)建后再將緩存應(yīng)用到表上,以此達(dá)到數(shù)據(jù)的一致性,這個(gè)緩存的大小由參數(shù) innodb_online_alter_log_max_size 控制,默認(rèn)的大小為 128MB。
AlTER TABLE [index_type](index_col_name)
ALGORITHM [=] {DEFAULT|INPLACE|COPY}
LOCK [=] { DEFAULT| NONE| SHARED| EXCLUSIVE }
ALGORITHM 制定了創(chuàng)建和刪除索引的算法,COPY 選擇創(chuàng)建臨時(shí)表的方式;INPLACE 表示創(chuàng)建和刪除索引不需要?jiǎng)?chuàng)建臨時(shí)表;DEFAULT 會(huì)根據(jù)參數(shù) old_alter_table 來(lái)判斷是使用 INPLACE 算法還是 COPY 算法,該參數(shù)的默認(rèn)值為 OFF,表示采用 INPLACE 方式。
LOCK 指定了創(chuàng)建和刪除索引的時(shí)候添加鎖的情況,NONE 表示不添加任何的鎖;SHARE 表示添加 S 鎖;EXCLUSIVE 表示添加 X 鎖;DEFAULT 會(huì)根據(jù)并發(fā)性執(zhí)行一個(gè)鎖升級(jí)的過(guò)程,先判斷是否可以使用 NONE 模式,若不能,再判斷是否可以使用 SHARED 模式,否則將使用 EXCLUSIVE 模式。
三、聯(lián)合索引
聯(lián)合索引是指對(duì)表上的多個(gè)列進(jìn)行索引。從本質(zhì)上來(lái)說(shuō),聯(lián)合索引也是一棵B+ 樹。那么什么時(shí)候會(huì)使用到聯(lián)合索引呢?"WHERE a= xxx and b=xxx" 和 "WHERE a= xxx" 都能使用到聯(lián)合索引,但是"WHERE b= xxx"則使用不到這個(gè)索引,因?yàn)槿~子節(jié)點(diǎn)上的 b 值是無(wú)序的,這也是人們常說(shuō)的 —— 最左前綴匹配。除此之外,因?yàn)槁?lián)合索引已經(jīng)對(duì)鍵值進(jìn)行了排序處理,因此對(duì)于索引列的排序操作也能使用到索引。
四、覆蓋索引
覆蓋索引是指從索引中就可以得到查詢的記錄,而不需要查詢聚集索引中的整行記錄的所有信息,因此可以減少大量的 IO 操作。比如只查詢索引列的信息。
對(duì)于統(tǒng)計(jì)問(wèn)題而言,在同時(shí)存在輔助索引和聚集索引的情況下,InnoDB 存儲(chǔ)引擎會(huì)優(yōu)先使用輔助索引來(lái)進(jìn)行統(tǒng)計(jì),因?yàn)檩o助索引遠(yuǎn)小于聚集索引(輔助索引不需要維護(hù)整行記錄的全部信息)。
此外,在通常情況下,諸如(a,b)的聯(lián)合索引,一般是不可以選擇列 b 作為查詢條件。但是如果是統(tǒng)計(jì)操作,并且是覆蓋索引的,則優(yōu)化器會(huì)進(jìn)行選擇。
五、其他
當(dāng)訪問(wèn)的數(shù)據(jù)占整個(gè)表中數(shù)據(jù)的蠻大一部分時(shí)(一般是20%左右),即使存在可以使用的輔助索引,優(yōu)化器仍然會(huì)選擇通過(guò)聚集索引來(lái)查找數(shù)據(jù),因?yàn)轫樞蜃x要遠(yuǎn)大于離散讀。這是由當(dāng)前傳統(tǒng)機(jī)械硬盤的特性所決定的,即利用順序讀來(lái)替換隨機(jī)讀的查找。可以使用關(guān)鍵字 FORCE INDEX 來(lái)強(qiáng)制使用某個(gè)索引。
Multi-Range Read 優(yōu)化是 MySQL 5.6 開始支持的一種索引優(yōu)化方式,目的是為了減少磁盤的隨機(jī)訪問(wèn),并且將隨機(jī)訪問(wèn)轉(zhuǎn)化為較為順序的數(shù)據(jù)訪問(wèn),這對(duì)于 IO-bound 類型的 SQL 查詢語(yǔ)句可帶來(lái)性能極大的提升,適用于 range、ref、eq_ref 類型的查詢。
Index Condition Pushdown(索引下推) 優(yōu)化是 MySQL 5.6 開始支持的一種索引優(yōu)化方式,默認(rèn)開啟,使用 SET optimizer_switch = 'index_condition_pushdown=off'; 可以將其關(guān)閉。ICP 優(yōu)化可以有效的提高查詢效率,適用于 range、ref、eq_ref、ref_or_null 類型的查詢。
總結(jié)
以上是生活随笔為你收集整理的mysql -b -e_MySQL 的B+树索引.的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 618别乱花 高性能RTX 30游戏本推
- 下一篇: php如何操作mysql数据库代码_ph