在做开发过程中经常会接触数据库索引,不只是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. 如何提高码农产量,基于java的web快速开发平台之自定义表单开发随笔

    老板 :下班前一定写完? 程序猿:可以,下班前能一定给! 第二天早上上班~~~ 老板:这都第二天了,怎么没写完? 程序猿:我还没有下班呢! 哎!程序猿的痛啊 公司上线的项目有不少销售记录表,又是报价单 ...

  2. 后渗透之meterpreter使用攻略

    Metasploit中的Meterpreter模块在后渗透阶段具有强大的攻击力,本文主要整理了meterpreter的常用命令.脚本及使用方式.包含信息收集.提权.注册表操作.令牌操纵.哈希利用.后门 ...

  3. 前端面试题-HTML语义化标签

    一.HTML5语义化标签 标签 描述 <article> 页面独立的内容区域. <aside> 页面的侧边栏内容. <bdi> 允许您设置一段文本,使其脱离其父元素 ...

  4. 前端开发--nginx篇

    安装和启动 Mac上搭建nginx教程 通过Homebrew 安装nginx brew install nginx 配置 添加配置文件在 /usr/local/etc/nginx/servers 目录 ...

  5. mac 工具推荐

    传送门: https://github.com/jaywcjlove/awesome-mac/blob/master/README-zh.md

  6. json中存整形数值,前端返回为空

    实现目标: 在servlet中将整型数值转为json,然后在前端获取 问题描述: 前端获取为空,显示为:console.log打印为:{} 解决办法: 在servlet中将数值转为json格式再进行传 ...

  7. linux firewalld 防火墙操作命令

    查看防火墙的状态systemctl status firewalldTomcat默认使用8080端口,如果防火墙开启,需要开通8080端口firewall-cmd --zone=public --ad ...

  8. ubuntu16.04 + caffe + SSD + gpu 安装

    昨天我们买好了硬件,今天我们开始安装caffe了,我本人安装过caffe不下10次,每次都是一大堆问题,后来终于总结了关键要点,就是操作系统. 1. 千万不要用ubuntu17.10来安装, 2. 最 ...

  9. Android 版的多合一Office应用也正式向iOS开放了

    导读 在 Android 版的多合一 Office 应用「偷跑」不久后(官方证实上线时间比计划要早),为 iOS 准备的版本现在终于也结束 beta 测试正式上线了. 和只提供「有限」平板支持的 An ...

  10. 探究Spring Boot中的接收参数问题与客户端发送请求传递数据

    结合此篇参考Spring框架学习笔记(9)--API接口设计相关知识及具体编码实现 在使用Spring Boot进行接收参数的时候,发现了许多问题,之前一直都很忙,最近才稍微有空研究一下此问题. 网上 ...