SQL查询在SQL Server 2008标准上运行,但在企业上运行

时间:2011-10-18 17:43:13

标签: sql-server-2008

我在SQL Server 2008企业上运行查询时遇到问题。 查询是从另一个表插入到表,但它检查记录是否只插入一次。 查询执行如下操作:

insert into A(...)
--complex select from table B as b
WHERE NOT EXISTS (SELECT 1 FROM A WHERE id = b.id)

编辑:此查询执行以下操作: 如果来自B的“复数选择”选择记录45(即id = 45的记录)两次,则第一次记录45的where为真,则将其插入A. 然后出现第二个时间记录45,其中where条件为false,因此它不会在A中插入两次。

这个查询在SQL Server 2008标准版上运行正常,所以我认为问题是SQL Server版本之间的区别(比如默认设置不同或者什么) 我正在阅读最大插入提交大小,但我不确定这是否可能是问题。 没有错误消息,唯一可见的错误是在标准我得到记录45一次,在企业我得到它两次。 任何想法?

2 个答案:

答案 0 :(得分:1)

我很确定你说你使用标准版的行为是出于其他原因,而不是你认为的那样。

您似乎期望如果您的INSERT ed值包含重复项,那么INSERTED将会NOT EXISTS,因为新的存在,INSERT .. SELECT将评估为false添加了行。然而AFAIK并不是它应该工作的方式。查看下面的简单CREATE TABLE A(id INT PRIMARY KEY) CREATE TABLE B(id INT PRIMARY KEY) INSERT INTO A SELECT * FROM B

NOT EXISTS

提供以下计划

Simple Select

添加INSERT INTO A SELECT * FROM B WHERE NOT EXISTS (SELECT 1 FROM A WHERE id = B.id) 子句

A

按如下方式更改计划

Sub query

除了现在包括反半连接的计划之外,SQL Server还在SELECT上插入聚簇索引之前向计划添加了一个急切的假脱机。这是一个阻塞运算符,其目的是确保在将任何行插入B之前评估整个SORT(与Halloween Protection相关)。

但是,您可能不一定在计划中看到假脱机。例如SQL Server也可能选择使用另一个阻塞运算符,例如{{1}}或散列反半连接。

请至少发布标准版的执行计划,最好是两者。还有查询,所以我们可以看到你是否正在使用任何不确定的结构。

答案 1 :(得分:0)

尝试重构您的查询,看看它是否有效。而不是NOT EXISTS连接插入查询中的表:

INSERT A(...)
SELECT ... FROM B LEFT JOIN A ON B.id = A.id
WHERE B.id = 45 AND A.id IS NULL

然后您只执行一次选择。