在做开发过程中经常会接触数据库索引,不只是DBA才需要知道索引知识,了解索引可以让我们写出更高质量代码。

  1. 索引概述
  2. 聚集索引
  3. 非聚集索引
  4. 唯一索引
  5. 筛选索引
  6. 非聚集索引包含列

索引概述

索引的存在主要为了提高数据检索速度,设计高效的索引对于获得良好的数据库和应用程序性能极为重要。

索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息,就像平常我们用的新华字典的目录,假如新华字典没有目录有找一个字就必须从第一页一直翻到最后一页,这是多么令人绝望的事情。

  索引是占有而外空间,是一种典型的空间换时间的做法,所以对待索引必须要保持敬畏之心,要建立在经常筛选的条件上,查询数据要时刻想着利用索引,竟然都花额外空间存储索引,不能让它白白浪费掉。

聚集索引

聚集索引基于数据行的键值在表内排序和存储这些数据行。 每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储。  

简单来说就是聚集索引和数据的存放顺序是一致的,聚集索引叶节点就是数据。

创建准则

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)

【SQL SERVER】索引的更多相关文章

  1. 【译】SQL Server索引进阶第八篇:唯一索引

    原文:[译]SQL Server索引进阶第八篇:唯一索引     索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就 ...

  2. 转: SQL Server索引的维护 - 索引碎片、填充因子

    转:http://www.cnblogs.com/kissdodog/archive/2013/06/14/3135412.html 实际上,索引的维护主要包括以下两个方面: 页拆分 碎片 这两个问题 ...

  3. SQL Server索引 (原理、存储)聚集索引、非聚集索引、堆 <第一篇>

    一.存储结构 在SQL Server中,有许多不同的可用排列规则选项. 二进制:按字符的数字表示形式排序(ASCII码中,用数字32表示空格,用68表示字母"D").因为所有内容都 ...

  4. SQL Server 索引结构及其使用(一)

    转载:SQL Server 索引结构及其使用(一) 作者:freedk 一.深入浅出理解索引结构 实际上,您可以把索引理解为一种特殊的目录.微软的SQL SERVER提供了两种索引:聚集索引(clus ...

  5. SQL Server 索引的图形界面操作 <第十二篇>

    一.索引的图形界面操作 SQL Server非常强大的就是图形界面操作.关于索引方面也一样那么强大,很多操作比如说重建索引啊,查看各种统计信息啊,都能够通过图形界面快速查看和操作,下面来看看SQL S ...

  6. SQL Server索引设计 <第五篇>

    SQL Server索引的设计主要考虑因素如下: 检查WHERE条件和连接条件列: 使用窄索引: 检查列的选择性: 检查列的数据类型: 考虑列顺序: 考虑索引类型(聚集索引OR非聚集索引): 一.检查 ...

  7. SQL Server索引的维护 - 索引碎片、填充因子 <第三篇>

    实际上,索引的维护主要包括以下两个方面: 页拆分 碎片 这两个问题都和页密度有关,虽然两者的表现形式在本质上有所区别,但是故障排除工具是一样的,因为处理是相同的. 对于非常小的表(比64KB小得多), ...

  8. SQL Server索引进阶:第十级,索引内部结构

    原文地址: Stairway to SQL Server Indexes: Level 10,Index Internal Structure 本文是SQL Server索引进阶系列(Stairway ...

  9. SQL Server索引进阶:第九级,读懂执行计划

    原文地址: Stairway to SQL Server Indexes: Level 9,Reading Query Plans 本文是SQL Server索引进阶系列(Stairway to SQ ...

  10. SQL Server索引进阶:第八级,唯一索引

    原文地址: Stairway to SQL Server Indexes: Level 8,Unique Indexes 本文是SQL Server索引进阶系列(Stairway to SQL Ser ...

随机推荐

  1. python爬虫之selenium+打码平台识别验证码

    1.常用的打码平台:超级鹰.打码兔等 2.打码平台在识别图形验证码和点触验证码上比较好用 (1)12306点触验证码 from selenium import webdriver from selen ...

  2. 一文搞懂jvm内存结构

    一.jvm是干什么的? 大家都知道java是跨平台语言,一次编译可以在不同操作系统上运行,怎么做到的呢,看下图: javac把写的源代码(java文件),编译成字节码(class文件),字节码部署到l ...

  3. Java入门教程十(抽象类接口内部类匿名类)

    抽象类(abstract) 一个类只定义了一个为所有子类共享的一般形式,至于细节则交给每一个子类去实现,这种类没有任何具体的实例,只具有一些抽象的概念,那么这样的类称为抽象类. 在面向对象领域,抽象类 ...

  4. python xlwings Excel 内容截图

    import xlwings as xw from PIL import ImageGrab def excel_save_img(path, sheet=0, img_name="1&qu ...

  5. python之面向对象02

    在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法 1. __init__()方法 class Cat: def __init__(self,newname, ...

  6. Docker实战之Zookeeper集群

    1. 概述 这里是 Docker 实战系列第四篇.主要介绍分布式系统中的元老级组件 Zookeeper. ZooKeeper 是一个开源的分布式协调服务,是 Hadoop,HBase 和其他分布式框架 ...

  7. safari坑之 回弹

    博客地址: https://www.seyana.life/post/20 今天在使用safari浏览博客的时候, 发现在拉至顶部并产生回弹之后,头部导航隐藏了, 除非在上拉的时候,刚好达到顶部而不超 ...

  8. 如何提升.NET控制台应用体验?

    原文:Upgrade Your .NET Console App Experience 作者:Khalid Abuhakmeh 译文:Lamond Lu 在.NET生态系统中,控制台程序的表现相对较差 ...

  9. angular的开始历程

    开始写angular了,抑制不住的开心,比react差点开心,vue开始太虐 喜欢一个人要不要表个白?其实也没啥资格喜欢~!!考虑一段时间吧 9.29表白了,嗯,被拒绝的干脆利落 为他写了一首小诗歌, ...

  10. 简单的编写java的helloWord

    那么在上一章章节 http://www.cnblogs.com/langjunnan/p/6814641.html 我们简单的俩了解了一下什么是java和配置编写java的环境,本章呢我们学习如何编写 ...