一.索引簡介
眾所周知,索引是關(guān)系型數(shù)據(jù)庫中給數(shù)據(jù)庫表中一列或多列的值排序后的存儲結(jié)構(gòu),SQL的主流索引結(jié)構(gòu)有B+樹以及Hash結(jié)構(gòu),聚集索引以及非聚集索引用的是B+樹索引。這篇文章會總結(jié)SQL Server以及MySQL的InnoDB和MyISAM兩種SQL的索引。
SQL Sever索引類型有:唯一索引,主鍵索引,聚集索引,非聚集索引。
MySQL 索引類型有:唯一索引,主鍵(聚集)索引,非聚集索引,全文索引。
二.聚集索引
聚集(clustered)索引,也叫聚簇索引。
定義:數(shù)據(jù)行的物理順序與列值(一般是主鍵的那一列)的邏輯順序相同,一個表中只能擁有一個聚集索引。
單單從定義來看是不是顯得有點抽象,打個比方,一個表就像是我們以前用的新華字典,聚集索引就像是拼音目錄,而每個字存放的頁碼就是我們的數(shù)據(jù)物理地址,我們?nèi)绻樵円粋€“哇”字,我們只需要查詢“哇”字對應(yīng)在新華字典拼音目錄對應(yīng)的頁碼,就可以查詢到對應(yīng)的“哇”字所在的位置,而拼音目錄對應(yīng)的A-Z的字順序,和新華字典實際存儲的字的順序A-Z也是一樣的,如果我們中文新出了一個字,拼音開頭第一個是B,那么他插入的時候也要按照拼音目錄順序插入到A字的后面
創(chuàng)建聚集索引
如果不創(chuàng)建索引,系統(tǒng)會自動創(chuàng)建一個隱含列作為表的聚集索引。
1.創(chuàng)建表的時候指定主鍵(注意:SQL Sever默認主鍵為聚集索引,也可以指定為非聚集索引,而MySQL里主鍵就是聚集索引)
create table t1(
id int primary key,
name nvarchar(255)
)
三.非聚集索引
非聚集(unclustered)索引。
定義:該索引中索引的邏輯順序與磁盤上行的物理存儲順序不同,一個表中可以擁有多個非聚集索引。
其實按照定義,除了聚集索引以外的索引都是非聚集索引,只是人們想細分一下非聚集索引,分成普通索引,唯一索引,全文索引。如果非要把非聚集索引類比成現(xiàn)實生活中的東西,那么非聚集索引就像新華字典的偏旁字典,他結(jié)構(gòu)順序與實際存放順序不一定一致。
創(chuàng)建非聚集索引
SQLServer
CREATE NONCLUSTERED INDEX ItemNumber ON [dbo].[ItemGroupBy]
(
ItemNumber ASC
)WITH (FILLFACTOR = 90)
GO
總結(jié)
- 使用聚集索引的查詢效率要比非聚集索引的效率要高,但是如果需要頻繁去改變聚集索引的值,寫入性能并不高,因為需要移動對應(yīng)數(shù)據(jù)的物理位置
- 非聚集索引在查詢的時候可以的話就避免二次查詢,這樣性能會大幅提升。
- 不是所有的表都適合建立索引,只有數(shù)據(jù)量大表才適合建立索引,且建立在選擇性高的列上面性能會更好。
何時使用聚集索引或非聚集索引
| 動作描述 | 使用聚集索引 | 使用非聚集索引 |
|---|---|---|
| 列經(jīng)常被分組排序 | 應(yīng) | 應(yīng) |
| 返回某范圍內(nèi)的數(shù)據(jù) | 應(yīng) | 不應(yīng) |
| 一個或極少不同值 | 不應(yīng) | 不應(yīng) |
| 小數(shù)目的不同值 | 應(yīng) | 不應(yīng) |
| 大數(shù)目的不同值 | 不應(yīng) | 應(yīng) |
| 頻繁更新的列 | 不應(yīng) | 應(yīng) |
| 外鍵列 | 應(yīng) | 應(yīng) |
| 主鍵列 | 應(yīng) | 應(yīng) |
| 頻繁修改索引列 | 不應(yīng) | 應(yīng) |