1、雜湊表
2、有序陣列
3、搜尋樹
雜湊表一種以鍵—值,儲存的資料結構,雜湊的思路很簡單,處理步驟就是
把值放在陣列裡,用乙個雜湊函式把 key 換算成乙個確定的位置,然後把 value 放在陣列的這個位置。
缺點:1、只適用於等值查詢,區間查詢效率低
有序陣列
優點:1、在等值查詢和範圍查詢中很好
2、使用於靜態索引引擎
缺點:1、在需要更新資料的時候就麻煩了,你往中間插入乙個記錄就必須得挪動後面所有的記錄,成本太高
搜尋樹書中最經典的就是 二叉搜尋樹。
二叉樹是搜尋效率最高的,但是實際上大多數的資料庫儲存卻並不使用二叉樹。其原因是,索引不止存在記憶體中,還要寫到磁碟上。
可以想象,100萬節點的平衡二叉樹,樹高20,一次查詢可能要訪問20個資料塊,在機械硬碟時代,從磁碟隨機讀乙個資料塊需要 10 ms 左右的定址時間。也就是說,對於乙個 100 萬行的表,如果使用二叉樹來儲存,單獨訪問乙個行可能需要 20 個 10 ms 的時間,這個查詢可真夠慢的。
n叉樹:
以 innodb 的乙個整數字段索引為例,這個 n 差不多是 1200。這棵樹高是 4 的時候,就可以存 1200 的 3 次方個值,這已經 17 億了。考慮到樹根的資料塊總是在記憶體中的,乙個 10 億行的表上乙個整數字段的索引,查詢乙個值最多隻需要訪問 3 次磁碟。其實,樹的第二層也有很大概率在記憶體中,那麼訪問磁碟的平均次數就更少了。n 叉樹由於在讀寫上的效能優點,以及適配磁碟的訪問模式,已經被廣泛應用在資料庫引擎中了。
1、在innodb 中,資料都是根據主鍵順序以索引的形式存放,這種儲存方式的表稱為索引組織表。又因為前面我們提到的,innodb 使用了 b+ 樹索引模型,所以資料都是儲存在 b+ 樹中的。
2、每乙個索引在 innodb 中都對應一棵 b+樹。
索引型別分為:主鍵索引(聚簇索引)和非主鍵索引(二級索引)
那麼主鍵索引和非主鍵索引有什麼區別呢?
如果語句是 select * from t where id=500,即主鍵查詢方式,則只需要搜尋 id 這棵 b+ 樹;
如果語句是 select * from t where k=5,即普通索引查詢方式,則需要先搜尋 k 索引樹,得到 id 的值為 500,再到 id 索引樹搜尋一次。這個過程稱為回表。
也就是說,基於非主鍵索引的查詢需要多掃瞄一棵索引樹。因此,我們在應用中應該盡量使用主鍵查詢。
索引的維護
b+樹為了維護索引有序性,在插入新值的時候,需要做必要的維護,其中可能就涉及,頁** 和 頁合併。
頁**:
插入資料時發現當前資料頁已經滿了,根據 b+ 演算法,需要申請乙個新的資料頁,並且移動部分資料。
頁合併:
當相鄰兩個頁由於刪除了資料,利用率很低之後,會將資料頁做合併。合併的過程,可以認為是**過程的逆過程
什麼情況下應該使用自增主鍵,什麼情況下有不應該使用?
主鍵長度越小,普通索引的葉子節點就越小,普通索引佔據的空間就越小。
所以,從效能和空間的角度來看,自增主鍵往往是合適的。
訂單在下面這個表 t 中,如果我執行 select * from t where k between 3 and 5,需要執行幾次樹的搜尋操作,會掃瞄多少行?
mysql> create table t (
id int primary key,
k int not null default 0,
s varchar(16) not null default '',
index k(k))
engine=innodb;
insert into t values(100,1, 『aa'),(200,2,'bb'),(300,3,'cc'),(500,5,'ee'),(600,6,'ff'), (700,7,'gg');
1、在 k 索引樹上找到 k=3 的記錄,取得 id = 300;
2、再到 id 索引樹查到 id=300 對應的 r3;
3、在 k 索引樹取下乙個值 k=5,取得 id=500;
4、再回到 id 索引樹查到 id=500 對應的 r4;
5、在 k 索引樹取下乙個值 k=6,不滿足條件,迴圈結束。
在這個過程中,回到主鍵索引樹搜尋的過程,我們稱為回表。可以看到,這個查詢過程讀了 k 索引樹的 3 條記錄(步驟 1、3 和 5),回表了兩次(步驟 2 和 4)。在這個例子中,由於查詢結果所需要的資料只在主鍵索引上有,所以不得不回表。那麼,有沒有可能經過索引優化,避免回表過程呢?
由於覆蓋索引可以減少樹的搜尋次數,顯著提公升查詢效能,所以使用覆蓋索引是乙個常用的效能優化手段。
最左匹配原則
b+樹的索引結構,可以利用索引的「最左字首」,來定位記錄。
那麼問題來了,在建立聯合索引的時候,如何安排索引內的字段順序?
1、通過調整順序,可以少維護乙個索引,那麼往往就是需要優先考慮的。
2、節省空間,比如上面這個市民表的情況,name 欄位是比 age 欄位大的 ,那我就建議你建立乙個(name,age) 的聯合索引和乙個 (age) 的單字段索引。
上一段我們說到滿足最左字首原則的時候,最左字首可以用於在索引中定位記錄。這時,你可能要問,那些不符合最左字首的部分,會怎麼樣呢?
聯合索引(name, age)為例
mysql> select * from tuser where name like '張%' and age=10 and ismale=1;
在mysql 5.6 之前,如上查詢只能找到滿足 like 的 乙個乙個回表,到主鍵索引找出資料行,再對比字段值。
在mysql 5.6 之後,引入了索引下推,可以在索引遍歷過程中,對索引中包含的字段先做判斷,直接過濾掉不滿足條件的記錄,減少回表次數。
04 初始mysql語句
create database db1 charset utf8 檢視當前建立的資料庫 show create database db1 檢視所有的資料庫 show databases alter database db1 charset gbk drop database db1 use db1 ...
innodb 04 索引 B 樹索引
索引 若索引太多,應用程式的效能可能會受到影響。而索引太少,對查詢效能又會產生影響innodb儲存引擎支援以下幾種常見的索引 b 樹索引 全文索引 雜湊索引 innodb儲存引擎支援的雜湊索引是自適應的,innodb儲存引擎會根據表的使用情況自動為表生成雜湊索引,不能人為干預是否在一張表中生成雜湊索...
Mysql 04 索引 序列
3.刪除索引 4.檢視索引 二 序列 參考資料 來加快查詢的技術很多,其中最重要的是索引。通常索引能夠快速提高查詢速度 索引是在mysql的儲存引擎層中實現的,而不是在服務層實現的。所以每種儲存引擎的索引都不一定完全相同,也不是所有的儲存引擎都支援所有的索引型別。mysql目前提供了一下4種索引 h...