我试图提高多行INSERT查询的性能,根据查询计划,目前最大的因素是针对大型父表的FK验证。
我知道 INSERT查询不会插入违反FK的数据,因为它是 INSERT INTO ... SELECT ... FROM 查询SELECT涉及对键列的父表的INNER JOIN,因此插入的行中不存在无效值。
我不想全局禁用FK。当其他查询可能插入错误数据时,我不想打开一个窗口,并且在执行INSERT之前锁定表并禁用FK没有帮助,因为INSERT后重新启用FK意味着重新验证所有在引擎信任FK之前的行(WITH CHECK),两个表都很大(可能有数千万行,而且它是一个多列自然键)。
在单个INSERT查询的范围内,MSSQL中是否有任何方法可以禁用特定外键的验证?我真诚地希望(没有太多希望 [1] )我错过了解释该选项的文档。
[1]为什么引擎会信任用户在可能插入错误数据的查询中不使用该选项?对于LOCK TABLE - DISABLE FK - INSERT - ENABLE FK - UNLOCK TABLE方法来说,这似乎只是语法糖。但我不得不问以防万一......
答案 0 :(得分:2)
有时它是最好的解决方案。但通常不会。除此之外,没有办法做到这一点,除了之前禁用和之后重新启用。
ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column
然后,之后:
ALTER TABLE foo CHECK CONSTRAINT CK_foo_column
答案 1 :(得分:1)
你可以,但这是一个可怕,可怕,可怕的决定。而且没有免费的午餐。在某些时候,您必须验证约束 - 立即付款或稍后付款。稍后支付最终将意味着您的假设(所有行都有效)将被证明是错误的。
https://docs.microsoft.com/en-us/sql/relational-databases/indexes/disable-indexes-and-constraints
正如@Randeep所提到的,sql server不会自动创建支持FK的索引。这不能用于单个语句或单个连接 - 它对所有用户和特定表都是全局的。