Sql Server 索引之唯一索引和筛选索引

唯一索引(UNIQUE  INDEX)

当主键创建时如果不设置为聚集索引,那么就一定是唯一的非聚集索引。实际上,唯一索引,故名思议就是它要求该列上的值是唯一的。唯一索引能够保证索引键中不包含重复的值,从而使表中的每一行从某种方式上具有唯一性。 创建 UNIQUE 约束和创建与约束无关的唯一索引并没有明显的区别。进行数据验证的方式相同,而且对于唯一索引是由约束创建的还是手动创建的,查询优化器并不加以区分。 但是,创建列的 UNIQUE 约束会使索引目标更清晰。 Unique Constraints and Check Constraints." xml:space="preserve" id="mt6">在创建唯一索引时,可以设置一个忽略重复键的选项。 Yes and you attempt to create duplicate keys by adding data that affects multiple rows (with the INSERT statement), the row containing a duplicate is not added." xml:space="preserve" id="mt8">如果此选项已设置为“是”,当您试图通过添加影响多行的数据来创建重复键(使用 INSERT 语句)时,则不会添加包含重复项的行; No, the entire insert operation fails and all the data is rolled back." xml:space="preserve" id="mt9">如果此选项设置为“否”,则整个插入操作将失败,并且将回滚所有数据。

唯一索引的优点

  • 多列唯一索引能够保证索引键中值的每个组合都是唯一的。 例如,如果为 LastNameFirstName 和 MiddleName 列的组合创建了唯一索引,则表中的任意两行都不会有这些列值的相同组合。
  • 只要每个列中的数据是唯一的,就可以为同一个表创建一个唯一聚集索引和多个唯一非聚集索引。
  • 唯一索引能够确保定义的列的数据完整性。
  • 唯一索引提供帮助查询优化器生成更高效的执行计划的其他信息。

典型实现

唯一索引可通过以下方式实现:

  • PRIMARY KEY 或 UNIQUE 约束

在创建 PRIMARY KEY 约束时,如果不存在该表的聚集索引且未指定唯一非聚集索引,则将自动对一列或多列创建唯一聚集索引。 主键列不允许空值。

在创建 UNIQUE 约束时,默认情况下将创建唯一非聚集索引,以便强制 UNIQUE 约束。 如果不存在该表的聚集索引,则可以指定唯一聚集索引。

  • Unique Constraints and Check Constraints and Primary and Foreign Key Constraints. 

独立于约束的索引可以为一个表定义多个唯一非聚集索引。

  • 索引视图

若要创建索引视图,请对一个或多个视图列定义唯一聚集索引。 视图将执行,并且结果集存储在该索引的页级别中,其存储方式与表数据存储在聚集索引中的方式相同。

限制和局限

  • 如果数据中存在重复的键值,则不能创建唯一索引、UNIQUE 约束或 PRIMARY KEY 约束。
  • 唯一非聚集索引可以包括包含性非键列。

唯一索引依赖于唯一约束,删除唯一索引必须删除唯一约束。另外SQL Server又在建立唯一约束时又默认建立唯一索引。

过滤唯一索引,当我们需要既允许多个NULL值,又不允许重复的时候,可以使用这个:

  CREATE UNIQUE NONCLUSTERED INDEX xx on

  ProductDemo(<索引列>)  --指定索引列

  where <索引列>!=null)  --过滤条件

  对于用以上语法创建的唯一索引,插入时,只有当唯一索引列不为NULL的时候才检测重复。换句话说,以上表的索引列允许多个NULL值。

筛选索引(Filtered Index)

筛选索引是一种经过优化的非聚集索引,尤其适用于涵盖从定义完善的数据子集中选择数据的查询。 筛选索引使用筛选谓词对表中的部分行进行索引。 与全表索引相比,设计良好的筛选索引可以提高查询性能、减少索引维护开销并可降低索引存储开销。

筛选索引与全表索引相比具有以下优点:

  • 提高了查询性能和计划质量

设计良好的筛选索引可以提高查询性能和执行计划质量,因为它比全表非聚集索引小并且具有经过筛选的统计信息。 与全表统计信息相比,经过筛选的统计信息更加准确,因为它们只涵盖筛选索引中的行。

  • 减少了索引维护开销

仅在数据操作语言 (DML) 语句对索引中的数据产生影响时,才对索引进行维护。 与全表非聚集索引相比,筛选索引减少了索引维护开销,因为它更小并且仅在索引中的数据更改时才进行维护。 筛选索引的数量可以非常多,特别是在其中包含很少更改的数据时。 同样,如果筛选索引只包含频繁修改的数据,则索引大小较小时可以减少更新统计信息的开销。

  • 减少了索引存储开销

在没必要创建全表索引时,创建筛选索引可以减少非聚集索引的磁盘存储开销。 可以使用多个筛选索引替换一个全表非聚集索引而不会明显增加存储需求。

设计注意事项

  • 在列中只有少量相关值需要查询时,可以针对值的子集创建筛选索引。 例如,当列中的值大部分为 NULL 并且查询只从非 NULL 值中进行选择时,可以为非 NULL 数据行创建筛选索引。 由此得到的索引与对相同键列定义的全表非聚集索引相比,前者更小且维护开销更低。
  • 表中含有异类数据行时,可以为一种或多种类别的数据创建筛选索引。 通过将查询范围缩小为表的特定区域,这可以提高针对这些数据行的查询性能。 此外,由此得到的索引与全表非聚集索引相比,前者更小且维护开销更低。

限制和局限

  • 不能对视图创建筛选索引。 但是,查询优化器可以从对视图中引用的表定义的筛选索引中获益。 对于从视图中选择数据的查询,如果查询结果正确,查询优化器会考虑对此查询使用筛选索引。

筛选索引与索引视图相比,具有以下优点:

  • 减少了索引维护开销。 例如,相对于索引视图而言,查询处理器使用更少的 CPU 资源便可更新筛选的索引。
  • 改善了计划质量。 例如,在查询编译期间,查询优化器考虑使用筛选的索引的情况要比考虑使用等效的索引视图的情况多。
  • 联机索引重新生成。 您可以在筛选的索引可用于查询时重新生成它们。 索引视图不支持联机索引重新生成
  • 非唯一索引。 筛选索引可以是非唯一的,而索引视图必须是唯一的。
  • 筛选索引是针对一个表定义的,仅支持简单比较运算符。 如果需要引用多个表或具有复杂逻辑的筛选表达式,则应创建视图。
  • 如果筛选索引表达式等效于查询谓词并且查询并未在查询结果中返回筛选索引表达式中的列,则筛选索引表达式中的列不需要作为筛选索引定义中的键或包含列。
  • 如果查询谓词在不与筛选索引表达式等效的比较中使用了筛选索引表达式中的某列,则该列应为筛选索引定义中的键或包含列。
  • 如果筛选索引表达式中的某列在查询结果集中,则该列应为筛选索引定义中的键或包含列。
  • 表的聚集索引键不需要是筛选索引定义中的键或包含列。 聚集索引键自动包含在所有非聚集索引(包括筛选索引)中。
  • 如果筛选索引结果的筛选索引表达式中指定的比较运算符会导致隐式或显式数据转换,则转换发生在比较运算符的左边时,会出现错误。 解决方法是在比较运算符的右边编写包含数据转换运算符(CAST 或 CONVERT)的筛选索引表达式。
时间: 2024-08-07 00:17:07

Sql Server 索引之唯一索引和筛选索引的相关文章

mysql,sql server,oracle 唯一索引字段是否允许出现多个 null 值?

最近一个项目,涉及到sql server 2008,因为业务需求,希望建立一个唯一索引,但是发现在sql server中,唯一索引字段不能出现多个null值,下面是报错信息: CREATE UNIQUE NONCLUSTERED INDEX weixin_openid_ui ON Users(weixin_openid); 因为发现对象名称 'dbo.Users' 和索引名称 'weixin_openid_ui' 有重复的键,所以 CREATE UNIQUE INDEX 语句终止.重复的键值为

SQL Server调优系列基础篇(索引运算总结)

原文:SQL Server调优系列基础篇(索引运算总结) 前言 上几篇文章我们介绍了如何查看查询计划.常用运算符的介绍.并行运算的方式,有兴趣的可以点击查看. 本篇将分析在SQL Server中,如何利用先有索引项进行查询性能优化,通过了解这些索引项的应用方式可以指导我们如何建立索引.调整我们的查询语句,达到性能优化的目的. 闲言少叙,进入本篇的正题. 技术准备 基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析. 简介 所谓的索引应用就是在我们

SQL Server 得到SPID,唯一的sessionID

像.net中的session一样,如果能知道了数据库中的sessionID,那所有的操作都能知道了,因为有了这个唯一的身份识别的标识. 可以做的事情有很多,如:当前哪个用户在做什么操作,在执行什么sql, 又如一个比较大的逻辑中要分别执行很多存储过程, 在执行这些存储过程的过程当中,你想知道当前执行的进度,SQLServer正在执行哪个段sql语句,那么通过sessionID是很容易 就得到这些信息的. SQL Server 得到SPID,唯一的sessionID: SELECT @@SPID

SQL Server性能优化(9)聚集索引

一.索引的概念和分类 索引的概念大家都知道,日常开发中我们也会使用常见的聚集索引.非聚集索引.但是除了这两者以外,sqlserver中还提供其他的索引,如: a. 唯一索引:不包含重复键的索引,聚集索引或者非聚集索引都可以是唯一索引. b. 包含列的索引:它扩展后不仅包含键列,还包含非键列. c. 全文索引 d. 空间索引 e. 筛选索引 f. XML 当然以上几种除了a和b基本上没用到过. 二.聚集索引的结构 要想使用聚集索引,必须了解聚集索引的概念以及它的原理.网上对聚集索引描述的资料有很多

Sql Server查询性能优化之走出索引的误区

据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是,或者干脆把整个查询SQL直接发给DBA,让DBA直接帮忙优化了,所以造成的状况就是开发人员对于索引的理解.认识很局限,以下就把我个人对于索引的理解及浅薄认识和大家分享下,希望能解除一些大家的疑惑,一起走出索引的误区 误区1.在表上建立了索引,在查询时用到了索引的列,索引就一定会生效 首先明确下这样的

[SQL Server 2005/2008] select语句中指定索引

一般情况下,SQL Server的查询优化器会对查询做优化,选择适合的索引. 当遇到一些宽表,索引和where 过滤条件多时, 查询优化器选择的可能并不是最佳的索引, 此时需要手动指定索引.具体效果可以在“执行计划中查看”. select * from 表名 with (nolock, index(索引表)) where ........

Sql Server之旅——第八站 复合索引和include索引到底有多大区别?

周末终于搬进出租房了,装了宽带....才发现没网的日子...那是一个怎样的与世隔绝呀...再也受不了那样的日子了....好了,既然网 安上去了,还得继续我的这个系列. 索引和锁,这两个主题对我们开发工程师来说,非常的重要...只有理解了这两个主题,我们才能写出高质量的sql语句,在之前的博客中,我所说的 索引都是单列索引...当然数据库不可能只认单列索引,还有我这篇的复合索引,说到复合索引,可能熟悉的人又会说到include索引,那这两个索引到底 有什么区别呢,当然我也是菜鸟一枚...所以下面的

SQL Server 2016新特性:列存储索引新特性

行存储表可以有一个可更新的列存储索引,之前非聚集的列存储索引是只读的. 非聚集的列存储索引支持筛选条件. 在内存优化表中可以有一个列存储索引,可以在创建表的时候创建,也可以在之后的alter table语句上创建.之前内存优化表不支持列存储索引. 聚集的列存储索引可以有多个非聚集行存储索引,之前列存储索引不支持非聚集索引. 支持在聚集列存储索引上加入主键和外键约束,约束使用btree索引. 列聚集索引有一个压缩延迟选项,让事务复合收到的影响最小. 兼容级别为120,130的数据库性能: 列存储索

SQL Server统计信息:问题和解决方式

在网上看到一篇介绍使用统计信息出现的问题已经解决方式,感觉写的很全面. 在自己看的过程中顺便做了翻译. 因为本人英文水平有限,可能中间有一些错误. 假设有哪里有问题欢迎大家批评指正.建议英文好的直接看原文:SQL Server Statistics: Problems and Solutions 正文: SQL Server统计信息协助查询优化器计算执行查询的最优方式. Holger描写叙述了常见的统计信息出错的事情,而且怎样改善 通常你不须要太操心运行SQL查询的方式.他们被传送到查询优化器,

SQL Server统计信息:问题和解决方案

在网上看到一篇介绍使用统计信息出现的问题已经解决方案,感觉写的非常全面.在自己看的过程中顺便做了翻译.由于本人英文水平有限,可能中间有一些错误.如果有哪里有问题欢迎大家批评指正.建议英文好的直接看原文:SQL Server Statistics: Problems and Solutions 正文: SQL Server统计信息协助查询优化器计算运行查询的最优方式. Holger描述了常见的统计信息出错的事情,并且如何改善 通常你不需要太担心执行SQL查询的方式.他们被传送到查询优化器,首先检查