索引概述sql
索引的存在主要爲了提升數據檢索速度,設計高效的索引對於得到良好的數據庫和應用程序性能極爲重要。數據庫
索引是對數據庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問數據庫表中的特定信息,就像日常咱們用的新華字典的目錄,假如新華字典沒有目錄有找一個字就必須從第一頁一直翻到最後一頁,這是多麼使人絕望的事情。ide
索引是佔有而外空間,是一種典型的空間換時間的作法,因此對待索引必需要保持敬畏之心,要創建在常常篩選的條件上,查詢數據要時刻想着利用索引,居然都花額外空間存儲索引,不能讓它白白浪費掉。性能
彙集索引測試
彙集索引基於數據行的鍵值在表內排序和存儲這些數據行。 每一個表只能有一個彙集索引,由於數據行自己只能按一個順序存儲。 優化
簡單來講就是彙集索引和數據的存放順序是一致的,彙集索引葉節點就是數據。ui
建立準則spa
1. 定義彙集索引鍵時使用的列越少越好設計
2. 惟一或包含許多不重複的值(若建立彙集索引時沒使用惟一屬性,SQL Server會自動添加一個4字節的惟一標識列)
3. 常常須要順序訪問數據
4. 常常用於對錶中檢索到的數據進行排序
5. 列大小不超過900字節
適合使用匯集索引狀況
1. 使用運算符(如 BETWEEN、>、>=、< 和 <=)返回一系列值
2. 返回大型結果集
3. 使用 JOIN 子句;通常狀況下,使用該子句的是外鍵列
4. 使用 ORDER BY 或 GROUP BY 排序/分組數據(由於分組數據也是要先排序)
不適合使用匯集索引狀況
1. 頻繁更改的列,每次更改都會致使索引頁不斷從新構建。
2. 若干列或若干大型列的組合,每次構建排序須要大量計算
TSQL建立彙集索引
--惟一的彙集索引 CREATE UNIQUE CLUSTERED INDEX [IX_TableName_Name] ON [dbo].[TableName] ([FieldName] ASC) --不惟一的彙集索引 CREATE CLUSTERED INDEX [IX_TableName_Name] ON [dbo].[TableName] ([FieldName] ASC)
非彙集索引
非彙集索引包含索引鍵值和指向表數據存儲位置的行定位器。 能夠對錶或索引視圖建立多個非彙集索引。 一般,設計非彙集索引是爲改善常用的、沒有創建彙集索引的查詢的性能。
簡單來講不是彙集索引的就是非彙集索引。額,好像沒解釋同樣。。。非彙集索引的葉節點是定位器。
建立準則
1. 不超過1700字節(其餘文檔說是900字節,我測試SQL Server是1700字節)
2. 避免添加沒必要要的列,由於增長索引維護成本
3. 包含許多不重複的值,這樣才能更好利用索引查詢效率
4. 列的長度儘量小
適合使用非彙集索引狀況
1. 使用 JOIN 或 GROUP BY 子句
2. 不返回大型結果集的查詢
3. 常常包含在查詢的搜索條件中的列
不適合使用非彙集索引狀況
1. 列的重複值較少
2. 不是常常查詢的搜索條件的列
3. 列的長度過長,由於增長索引維護成本
彙集索引與非彙集索引區別(知識有限,未必全,但願補充)
1. 彙集索引是按物理順序排列,非彙集索引邏輯順序排列
2. 彙集索引一個表只能有一個,非彙集索引能夠多個
3. 彙集索引的葉節點是數據,非彙集索引的葉節點是定位器
4. 彙集索引不能附加信息,非彙集索引能夠包含附加信息
TSQL建立非彙集索引
CREATE INDEX IX_TableName_FieldName ON DataTable(FieldName DESC)
惟一索引
惟一索引可以保證索引鍵中不包含重複的值,從而使表中的每一行從某種方式上具備惟一性。 只有當惟一性是數據自己的特徵時,指定惟一索引纔有意義。
保證索引鍵中不包含重複的值(包含NULL值)
建立準則
1. 只有須要保證數據惟一性的狀況下才使用
適合使用惟一索引狀況
1. 須要保證數據惟一性
不適合使用惟一索引狀況
1. 不須要保證數據惟一性
TSQL建立惟一索引
CREATE UNIQUE INDEX IX_TableName_FieldName ON DataTable(FieldName ASC)
篩選索引
篩選索引是一種通過優化的非彙集索引,尤爲適用於涵蓋從定義完善的數據子集中選擇數據的查詢。 篩選索引使用篩選謂詞對錶中的部分行進行索引。
只把符合條件的數據作索引,至關於在一個表的子集作索引。從而達到下面幾個好處
1. 提升了查詢性能 ,由於索引頁的數據比全表索引小
2. 減小索引維護開銷,由於只有符合條件纔會對索引頁維護
3. 減小索引存儲開銷,道理跟上面同樣
建立準則
1. 篩選的條件必須是明確的值
2. 一般來講常常查詢出現的條件跟過濾條件符合
3. 常常檢索的都是數據的子集
適合使用篩選索引狀況
1. 常常篩選表的子集數據,例如一般咱們只查詢有效的訂單,無效的訂單不多查,或者基本不查,這種狀況適合創建篩選索引
2. 只查最近數據,例如記錄只查最近一個月,能夠經過按期在數據庫空閒的時從新維護篩選索引達到加快查詢效率
不適合使用篩選索引狀況
1. 常常查詢條件包含篩選值外,這樣致使走全表掃描(前提沒其餘索引覆蓋到)
2. 查詢條件不固定
TSQL建立惟一索引
CREATE INDEX IX_TableName_FieldName ON [dbo].[TableName](FieldName ASC) where State > 1
非彙集索引包含列
經過將非鍵列添加到非彙集索引的葉級,擴展非彙集索引的功能。 經過包含非鍵列,能夠建立覆蓋更多查詢的非彙集索引
經過把包含的列同時維護在索引頁,達到當查詢的數據都包含在索引中的數據的時候,由於在索引頁找到全部數據,就不須要訪問表的數據頁,從而減小I/O操做,這種一般稱爲「覆蓋查詢」
建立準則
1. 必須至少定義一個鍵列
2. 在 CREATE INDEX 語句的 INCLUDE 子句中定義非鍵列
3. 只能對錶或索引視圖的非彙集索引定義非鍵列
4. 容許除 text、 ntext和 image以外的全部數據類型
5. 精確或不精確的肯定性計算列均可以是包含列
6. 不能同時在 INCLUDE 列表和鍵列列表中指定列名
7. INCLUDE 列表中的列名不能重複
8. 索引鍵列(不包括非鍵)必須遵照現有索引大小的限制
9. 全部非鍵列的總大小隻受 INCLUDE 子句中所指定列的大小限制;例如, varchar(max) 列限制爲 2 GB
適合使用非彙集索引包含列
1. 篩選的列是索引鍵 && 查詢的列都是包含的列
不適合使用非彙集索引包含列
2. 篩選的列不是索引鍵 || 查詢的列有不在包含列中的
TSQL建立篩選索引
CREATE INDEX IX_TableName_FieldName ON DataTable(Field1 ASC) INCLUDE(Field2)