设为首页 收藏本站
查看: 731|回复: 0

[经验分享] SQL Constraints – CHECK and NOCHECK

[复制链接]

尚未签到

发表于 2016-11-11 02:18:17 | 显示全部楼层 |阅读模式
SQL Constraints – CHECK and NOCHECK
One performance issue i faced at a recent project was with the way that our constraints were being managed, we were using Subsonic as our ORM, and it has a useful tool for generating your ORM code called SubStage – once configured, you can regenerate your DAL code easily based on your database schema, and it can even be integrated into your build as a pre-build event if you want to do this.  SubStage also offers the useful feature of being able to generate DDL scripts for your entire database, and can script your data for you too.
The problem came when we decided to use the generate scripts feature to migrate the database onto a test database instance – it turns out that the DDL scripts that it generates include the WITH NOCHECK option, so when we executed them on the test instance, and performed some testing, we found that performance wasn’t as expected.
A constraint can be disabled, enabled but not trusted, or enabled and trusted.  When it is disabled, data can be inserted that violates the constraint because it is not being enforced, this is useful for bulk load scenarios where performance is important.  So what does it mean to say that a constraint is trusted or not trusted?  Well this refers to the SQL Server Query Optimizer, and whether it trusts that the constraint is valid.  If it trusts the constraint then it doesn’t check it is valid when executing a query, so the query can be executed much faster.
Here is an example base in this article on TechNet, here we create two tables with a Foreign Key constraint between them, and add a single row to each.  We then query the tables:

1 DROP TABLE t2
2 DROP TABLE t1
3 GO
4  
5 CREATE TABLE t1(col1 int NOT NULL PRIMARY KEY)
6 CREATE TABLE t2(col1 int NOT NULL)
7  
8 ALTER TABLE t2 WITH CHECK ADD CONSTRAINT fk_t2_t1 FOREIGN KEY(col1)
9 REFERENCES t1(col1)
10
11 INSERT INTO t1 VALUES(1)
12 INSERT INTO t2 VALUES(1)
13 GO
14
15 SELECT COUNT(*) FROM t2
16 WHERE EXISTS
17 (SELECT *
18 FROM t1
19 WHERE t1.col1 = t2.col1)

This all works fine, and in this scenario the constraint is enabled and trusted.  We can verify this by executing the following SQL to query the ‘is_disabled’ and ‘is_not_trusted’ properties:
1 select name, is_disabled, is_not_trusted from sys.foreign_keys
This gives the following result:
DSC0000.png
We can disable the constraint using this SQL:
And when we query the constraints again, we see that the constraint is disabled and not trusted:
So the constraint won’t be enforced and we can insert data into the table t2 that doesn’t match the data in t1, but we don’t want to do this, so we can enable the constraint again using this SQL:
1 alter table t2 CHECK CONSTRAINT fk_t2_t1
But when we query the constraints again, we see that the constraint is enabled, but it is still not trusted:
DSC0001.png
This means that the optimizer will check the constraint each time a query is executed over it, which will impact the performance of the query, and this is definitely not what we want, so we need to make the constraint trusted by the optimizer again.
First we should check that our constraints haven’t been violated, which we can do by running DBCC:
1 DBCC CHECKCONSTRAINTS (t2)
Hopefully you see the following message indicating that DBCC completed without finding any violations of your constraint:
DSC0002.png
Having verified that the constraint was not violated while it was disabled, we can simply execute the following SQL:
1 alter table t2 WITH CHECK CHECK CONSTRAINT fk_t2_t1
At first glance this looks like it must be a typo to have the keyword CHECK repeated twice in succession, but it is the correct syntax and when we query the constraints properties, we find that it is now trusted again:
DSC0003.png
To fix our specific problem, we created a script that checked all constraints on our tables, using the following syntax:
1 ALTER TABLE t2 WITH CHECK CHECK CONSTRAINT ALL

http://geekswithblogs.net/dturner/archive/2011/01/31/sql-constraints-check-and-nocheck.aspx

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-298464-1-1.html 上篇帖子: ASP应用之中经常用SQL语句 下篇帖子: 深入SQL语句性能调整
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表