前言1:我會結合mysql和mssql來寫。雖然是不一樣的數據庫,可是兩者索引的本質是同樣的。mysql
前言2:業務系統大多數時間無非動態條件+排序+查找,如何提高排序查找效率乃重中之重算法
前言3:程序猿的救命稻草——建立索引sql
若是你對前言的內容感興趣(怎麼會有興趣呢,很痛苦好吧。。。)不過爲了未來數據庫
請繼續往下看吧bash
1 索引的定義數據結構
不須要太多術語,就一句話:快速查找&有序 的數據結構工具
堆表不保證有序性能
彙集索引Clustered Index
1 列能夠有重複值。
2若是主鍵默認作彙集索引,則符合惟一約束.
3索引組織表是有序的,堆表是無序的。
4只能有一個
5mysql的表就是一張索引組織表,若無主鍵,InnoDB engine會自動建立一個6字節(48bit)列做爲主鍵。mssql則不會
6當select * 的時候,檢索最快,由於葉子節點有所有的數據
非彙集索引NonClustered Index
1葉子節點上保存二個信息:索引字段值,對應彙集索引鍵值(無彙集索引,則是數據位置的指針)
2select * 浪費性能,須要標籤查找。select 非彙集列 則最快複製代碼
快問快答——ui
主鍵和彙集索引有什麼區別?miemiemie~~spa
3 索引在執行計劃中的術語
結構
|
SCAN
|
SEEK
|
堆(沒有彙集索引的表格數據頁)
|
Table Scan
沒有彙集索引
|
無
|
彙集索引
|
Clustered Index Scan
有彙集索引,但也是全表掃描
|
Clustered index seek
用索引結果檢索Data
|
非彙集索引
|
Index Scan
有非彙集索引,只是小部分Data掃描,比整表掃描代價小得多
|
index seek
用索引結果檢索Data
|
1 索引是一個B+樹
B+樹的概念,網上一大堆,這裏不贅述。我用一個圖來展現B+樹是如何插入元素的。
2 索引插入算法—— 靈魂畫手
3 索引分頁三個基本類型
彙集索引結點級(非leaf),彙集索引葉級別(就是數據行),非彙集索引結點級,非彙集索引的葉級別。
下一個章節會對索引分頁詳細說明,其中彙集索引葉級別,非彙集索引結點級不作細節介紹。
1 Sqlserver 一個分頁是8k,mysql一個分頁則是16k。存儲理論是一致的。
2
PageType(分頁類型)
|
1:數據頁面;2:索引頁面;3:Lob_mixed_page;4:Lob_tree_page;10:IAM頁面
|
IndexID (索引ID)
|
0 表明堆, 1 表明彙集索引, 2-250 表明非彙集索引 ,大於250就是text或image字段
|
sysindexes keycnt
|
0堆;1惟一彙集索引;2不帶惟一彙集索引、惟一非彙集索引
|
A彙集索引的節點行(非leaf)
組成:索引鍵值+下級指針
dbcc page(test,1,162,1) --索引leafdbcc page(test,1,178,1) -- 索引節點dbcc page(test,1,898,1) --根索引複製代碼
B非彙集索引的葉級行
1 非彙集索引+堆表
組成:非彙集鍵+ RID
組成:非彙集鍵值+彙集鍵值
組成:非彙集鍵值+向下指針
1 在項目中,我見過索引列數據類型是 varchar(500)的
做爲索引鍵值的列,數據類型太大
從上面能夠得知,數據頁大小是固定的.
一個索引行越長,那麼一個數據頁所能容納的索引就越少,這樣索引樹就會複雜。
查詢的時候產生的io就越多。
而數據庫的查詢處理器在選擇執行計劃的時候,若是使用索引的成本過高,那麼數據庫就會選擇全表掃描,那麼添加索引的意義在哪兒呢?複製代碼
2物理表隨意加索引
從問題1過渡過來,若是索引過多了,會怎樣呢?
有的攻城獅真的不要太大方,索引嗷嗷的加。最後索引比真正數據文件還要大。。。
索引是落磁盤的,是增長存儲壓力的。索引越多統計信息就越多,寫入會變慢。
那麼,應該怎麼加呢?
應該參考業務需求,熱點表熱點查詢加索引,爭取一個索引能夠覆蓋多個查詢。複製代碼
/*
* 索引實際大小
* 獲得索引名字
* Jaki Wang
*/
create function fn_Index_name(@object_id int,@index_id int)
returns sysname
as
begin
declare @index_name sysname
select @index_name = name
from sys.indexes
where object_id=@object_id and index_id=@index_id
return @index_name
end複製代碼