數據庫--索引
一、索引介紹
一般的應用系統,讀寫比例在10:1左右,而且插入操作和一般的更新操作很少出現性能問題,遇到最多最容易出問題的還是一些復雜的查詢操作,因此對查詢語句的優化顯然是重中之重。
索引相當於書的目錄,可以幫助用戶快速的找到需要的內容
在MySQL中也叫做鍵,是存儲引擎用於快速找到記錄的一種數據結構。能夠大大提高查詢效率。特別是當數據量非常大,查詢涉及多個表時,使用索引往往能使查詢速度加快成千上萬倍。
總結:
索引的目的在於提高查詢效率,與我們查閱圖書所用的目錄是一個道理:先定位到章,然後定位到該章下的一個小節,然後找到頁數。本質都是通過不斷地縮小想要獲取數據的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,我們可以總是用同一種查找方式來鎖定數據。
二、索引方法
1.BTREE 索引
一種將索引值按一定的算法,存入一個樹形的數據結構中
系統從磁盤讀取數據到內存時是以磁盤塊(block)為基本單位的,位於同一磁盤塊中的數據會被一次性讀取出來,而不是按需讀取。InnoDB 存儲引擎使用頁作為數據讀取單位,頁是其磁盤管理的最小單位,默認 page 大小是 16kB。
如上圖,是一顆b+樹,關於b+樹的定義可以參見B+樹,這裏只說一些重點,淺藍色的塊我們稱之為一個磁盤塊,可以看到每個磁盤塊包含幾個數據項(深藍色所示)和指針(黃色所示),如磁盤塊1包含數據項17和35,包含指針P1、P2、P3,P1表示小於17的磁盤塊,P2表示在17和35之間的磁盤塊,P3表示大於35的磁盤塊。真實的數據存在於葉子節點即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非葉子節點不存儲真實的數據,只存儲指引搜索方向的數據項,如17、35並不真實存在於數據表中。
b+樹的查找過程
如圖所示,如果要查找數據項29,那麽首先會把磁盤塊1由磁盤加載到內存,此時發生一次IO,在內存中用二分查找確定29在17和35之間,鎖定磁盤塊1的P2指針,內存時間因為非常短(相比磁盤的IO)可以忽略不計,通過磁盤塊1的P2指針的磁盤地址把磁盤塊3由磁盤加載到內存,發生第二次IO,29在26和30之間,鎖定磁盤塊3的P2指針,通過指針加載磁盤塊8到內存,發生第三次IO,同時內存中做二分查找找到29,結束查詢,總計三次IO。真實的情況是,3層的b+樹可以表示上百萬的數據,如果上百萬的數據查找只需要三次IO,性能提高將是巨大的,如果沒有索引,每個數據項都要發生一次IO,那麽總共需要百萬次的IO,顯然成本非常非常高。
強烈註意: 索引字段要盡量的小,磁盤塊可以存儲更多的索引.
2.HASH 索引
hash就是一種(key=>value)形式的鍵值對,允許多個key對應相同的value,但不允許一個key對應多個value,為某一列或幾列建立hash索引,就會利用這一列或幾列的值通過一定的算法計算出一個hash值,對應一行或幾行數據. hash索引可以一次定位,不需要像樹形索引那樣逐層查找,因此具有極高的效率.
假設索引使用hash函數f( ),如下:
1 2 3 4 |
f( ‘Arjen‘ ) = 2323
f( ‘Baron‘ ) = 7437
f( ‘Peter‘ ) = 8784
f( ‘Vadim‘ ) = 2458
|
此時,索引的結構大概如下:
3.HASH與BTREE比較:
hash類型的索引:查詢單條快,範圍查詢慢 btree類型的索引:b+樹,層數越多,數據量越大,範圍查詢和隨機查詢快(innodb默認索引類型) 不同的存儲引擎支持的索引類型也不一樣 InnoDB 支持事務,支持行級別鎖定,支持 Btree、Hash 等索引,不支持Full-text 索引; MyISAM 不支持事務,支持表級別鎖定,支持 Btree、Full-text 等索引,不支持 Hash 索引; Memory 不支持事務,支持表級別鎖定,支持 Btree、Hash 等索引,不支持 Full-text 索引; NDB 支持事務,支持行級別鎖定,支持 Hash 索引,不支持 Btree、Full-text 等索引; Archive 不支持事務,支持表級別鎖定,不支持 Btree、Hash、Full-text 等索引;
dg \
數據庫--索引