索引概述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)