SQL Server中使用Check约束提升性能
在SQL Server中,SQL语句的执行是依赖查询优化器生成的执行计划,而执行计划的好坏直接关乎执行性能。
在查询优化器生成执行计划过程中,需要参考元数据来尽可能生成高效的执行计划,因此元数据越多,则执行计划更可能会高效。所谓需要参考的元数据主要包括:索引、表结构、统计信息等,但还有一些不是很被注意的元数据,其中包括本文阐述的Check约束。
查询优化器在生成执行计划之前有一个阶段叫做代数树优化,比如说下面这个简单查询:

图1.简单查询
查询优化器意识到1=2这个条件是永远不相等的,因此不需要返回任何数据,因此也就没有必要扫描表,从图1执行计划可以看出仅仅扫描常量后确定了1=2永远为false后,就可完成查询。
那么Check约束呢
Check约束可以确保一列或多列的值符合表达式的约束。在某些时候,Check约束也可以为优化器提供信息,从而优化性能,比如看图二的例子。

图2.有Check约束的列提升查询性能
图2是一个简单的例子,有时候在分区视图中应用Check约束也会提升性能,测试代码如下:
CREATE TABLE [dbo].[Test2007](
[ProductReviewID] [int] IDENTITY(1,1) NOT NULL,
[ReviewDate] [datetime] NOT NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Test2007] WITH CHECK ADD CONSTRAINT [CK_Test2007] CHECK (([ReviewDate]>='2007-01-01' AND [ReviewDate]<='2007-12-31'))
GO
ALTER TABLE [dbo].[Test2007] CHECK CONSTRAINT [CK_Test2007]
GO
CREATE TABLE [dbo].[Test2008](
[ProductReviewID] [int] IDENTITY(1,1) NOT NULL,
[ReviewDate] [datetime] NOT NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Test2008] WITH CHECK ADD CONSTRAINT [CK_Test2008] CHECK (([ReviewDate]>='2008-01-01' AND [ProductReviewID]<='2008-12-31'))
GO
ALTER TABLE [dbo].[Test2008] CHECK CONSTRAINT [CK_Test2008]
GO
INSERT INTO [Test2008] values('2008-05-06')
INSERT INTO [Test2007] VALUES('2007-05-06')
CREATE VIEW testPartitionView
AS
SELECT * FROM Test2007
UNION
SELECT * FROM Test2008
SELECT * FROM testPartitionView
WHERE [ReviewDate]='2007-01-01'
SELECT * FROM testPartitionView
WHERE [ReviewDate]='2008-01-01'
SELECT * FROM testPartitionView
WHERE [ReviewDate]='2010-01-01'
代码清单1.
我们针对Test2007和Test2008两张表结构一模一样的表做了一个分区视图。并对日期列做了Check约束,限制每张表包含的数据都是特定一年内的数据。当我们对视图进行查询并给定不同的筛选条件时,可以看到结果如图3所示。

图3.不同的条件产生不同的执行计划
由图3可以看出,当筛选条件为2007年时,自动只扫描2007年的表,2008年的表也是同样。而当查询范围超出了2007和2008年的Check约束后,查询优化器自动判定结果为空,因此不做任何IO操作,从而提升了性能。
结论
在Check约束条件为简单的情况下(指的是约束限制在单列且表达式中不包含函数),不仅可以约束数据完整性,在很多时候还能够提供给查询优化器信息从而提升性能。
SQL Server中使用Check约束提升性能的更多相关文章
- SQL Server中一个隐性的IO性能杀手-Forwarded record
简介 最近在一个客户那里注意到一个计数器很高(Forwarded Records/Sec),伴随着间歇性的磁盘等待队列的波动.本篇文章分享什么是forwarded record,并从原理上谈一 ...
- SQL Server中提前找到隐式转换提升性能的办法
http://www.cnblogs.com/shanksgao/p/4254942.html 高兄这篇文章很好的谈论了由于数据隐式转换造成执行计划不准确,从而造成了死锁.那如果在事情出现之前 ...
- SQL SERVER中用户定义标量函数(scalar user defined function)的性能问题
用户定义函数(UDF)分类 SQL SERVER中的用户定义函数(User Defined Functions 简称UDF)分为标量函数(Scalar-Valued Function)和表值函数(T ...
- SQL Server中多表连接时驱动顺序对性能的影响
本文出处:http://www.cnblogs.com/wy123/p/7106861.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
- SQL Server中约束的介绍
SQL Server中约束的介绍(转载收藏) Posted on 2010-09-03 11:05 grayboy 阅读(8501) 评论(0) 编辑 收藏 作者:GrayBoy 出处:http:// ...
- 为什么SQL语句Where 1=1 and在SQL Server中不影响性能
最近一个朋友和我探讨关于Where 1=1 and这种形式的语句会不会影响性能.最后结论是不影响. 虽然结论正确,但对问题的认识却远远没有解决问题的根本.实际上在T-SQL语句的书写过 ...
- SQL Server 中几种常见的约束关系
1.创建唯一约束 当表中已创建主键,但又要保证其他数据列的值唯一时,可以使用唯一约束,并且唯一约束允许NULL值(只有一个) (1)展开指定的数据库: (2)右击要创建唯一约束的表,在弹出的快捷菜单中 ...
- SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因
原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...
- SQL Server中的事务与其隔离级别之脏读, 未提交读,不可重复读和幻读
原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...
随机推荐
- GRU(Gated Recurrent Unit) 更新过程推导及简单代码实现
GRU(Gated Recurrent Unit) 更新过程推导及简单代码实现 RNN GRU matlab codes RNN网络考虑到了具有时间数列的样本数据,但是RNN仍存在着一些问题,比如随着 ...
- ps教程连接
教程1:http://www.68ps.com/jc/ps_tp.asp 教程2:http://www.3lian.com/edu/photoshop/
- CentOS 7.x设置自定义开机启动,添加自定义系统服务
Centos 系统服务脚本目录: /usr/lib/systemd/ 有系统(system)和用户(user)之分, 如需要开机没有登陆情况下就能运行的程序,存在系统服务(system)里,即: /l ...
- eclipse安装hibernate-Tools
启动eclipse 选择Help -> About Eclipse 记住自己的eclipse版本 访问http://download.jboss.org/jbosstools/updates/s ...
- windows下面安装Python和pip终极教程
在大二的时候接触过一段时间的Python,最近又开始玩起了这门语言.总的来说,个 人很喜欢Python的语言风格,但是这门语言对于windows并不算很友好,因为如果是初学者在windows环境下安装 ...
- WindowManager.LayoutParams 札记
WindowManager.LayoutParams wlp = new WindowManager.LayoutParams(width, height, WindowManager.LayoutP ...
- JS获取当前时间戳的方法
JavaScript 获取当前时间戳:第一种方法: var timestamp = Date.parse(new Date()); 结果:1280977330000第二种方法: var timesta ...
- mac安装虚拟机
1. 安装VirtualBox 2. 新建,按照步骤一步步选择 3.安装系统镜像 xp_sp3_74070.iso CN_WIN7_SP1_X64_33in1_V1.2.iso 设置磁盘分区等 4.V ...
- (转)win7 64 安装mysql-python:_mysql.c(42) : fatal error C1083: Cannot open include file: 'config-win.h': No such file or directory
原文地址:http://www.cnblogs.com/fnng/p/4115607.html 作者:虫师 今天想在在win7 64位环境下使用python 操作mysql 在安装MySQL-pyth ...
- bzoj3555: [Ctsc2014]企鹅QQ (Hash)
枚举每个分段的点,每次O(n)更新左边和右边的hash值 然后用双指针O(n)计算答案 #include<stdio.h> #include<string.h> #includ ...