在做开发过程中经常会接触数据库索引,不只是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. 非对称加密算法RSA 学习

    非对称加密算法RSA 学习 RSA加密算法是一种非对称加密算法.RSA是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Ad ...

  2. 纯JS实现KeyboardNav(学习笔记)一

    纯JS实现KeyboardNav(学习笔记)一 这篇博客只是自己的学习笔记,供日后复习所用,没有经过精心排版,也没有按逻辑编写 GitHub项目源码 预览地址 最终效果 KeyboardNav使用指南 ...

  3. SUCTF checkin

    复现的时候看了源码...... 发现文件上传时会对文件内容以及后缀进行严格的检测 同时还有exif_imagetype   这个就用图片马就行绕过,绕过文件后缀试一下传图片马解析为php 但是常规解析 ...

  4. nes 红白机模拟器 第7篇 编译使用方法

    模拟器,基于 InfoNES ,作者添加修改以下功能: 1, joypad 真实手柄驱动程序(字符型设备驱动) 2,原始图像只有256*240 ,添加 图像放大算法,这里实现了2种,a, 最近邻插值 ...

  5. go package 学习笔记 —— strconv(string与其他基本数据类型(int, float, bool)的转换)

    strconv实现了go中基本数据类型与string之间的转换. How to use in go go doc:https://godoc.org/strconv import "strc ...

  6. Hyperledger Fabric ChainCode开发

    预览 Hyperledger Fabric的chaincode开发目前支持Go.Java.Node.js语言,下面以Go语言作为例子,我们先看下面的一个官方提供chaincode模板 ··· pack ...

  7. 手撸MyBatis从配置文件到读出数据库的模拟实现

    手动模拟MyBatis入门案例的底层实现: 需要了解的关键技术: java反射.动态代理(comming soon) 一.Mybatis入门案例 点击此处跳过入门案例 首先看一下MyBatis最基础的 ...

  8. JsonFormat 日期少了8个小时?还我

    JsonFormat 后日期少了8个小时什么鬼? 前言 今天测试的时候发现时间对不上,比数据库里的时间少了8个小时?测试小姐姐一顿狂轰乱炸,一点都不温柔. 什么鬼?哪里出了问题?数据库显示的是下面

  9. Docker深入浅出系列 | 5分钟搭建你的私有镜像仓库

    Docker已经上市很多年,不是什么新鲜事物了,很多企业或者开发同学以前也不多不少有所接触,但是有实操经验的人不多,本系列教程主要偏重实战,尽量讲干货,会根据本人理解去做阐述,具体官方概念可以查阅官方 ...

  10. 如何理解SiamRPN++?

    如何理解SiamRPN++? 目标跟踪: 使用视频序列第一帧的图像(包括bounding box的位置),来找出目标出现在后序帧位置的一种方法. 孪生网络结构: 在进入到正式理解SiamRPN++之前 ...