SQL Server 2008:执行计划包含错误数据?

发布于 2024-11-26 22:19:31 字数 1911 浏览 0 评论 0原文

考虑以下情况:

  1. 有一个包含数据 @XmlData 的 xml
  2. 将 @XmlData 提取到关系表 (@ItemList)
  3. 定义表变量 (@Table)
  4. 从 2 个 db 表(tblCdbA0 和 tblCdbG2)提取数据到 @XmlData使用exists 子句的表

下面是一个代码示例:

--1. There is an xml that contains data @XmlData 
declare @XmlData xml = '
<Root>
      <Item rid="522822E251CA11D18F1400A02427D15E" />
</Root>'

--2. The @XmlData is extracted into a relational table (@ItemList)
declare @ItemList table (ItemRid char(32) primary key);
insert into @ItemList(ItemRid)
select Tab.rid
from ( select Item.Rid.value('@rid','char(32)') rid
       from @XmlData.nodes('(/Root)[1]/Item') Item(Rid)) Tab
group by Tab.rid

--3. A table variable is defined (@table)
declare @Table TABLE 
(
    Rid char(32) primary key
   ,Rid1 char(32)
   ,Rid2 char(32)
)

--4. The data extracted from 2 db tables (tblCdbA0 and tblCdbG2) into @Table using exists clause
insert into @Table(Rid,Rid1,Rid2)
select A0.A0RID, A0.T4RID, A0.T6RID
from tblCdbA0 A0 with (nolock)
where 
exists (select null 
         from tblCdbG2 G2 with(nolock)
         inner join @ItemList Items
         on Items.ItemRid = G2.G0RID 
         where A0.A0RID=G2.A0RID)

表 tblCdbG2 包含 63582 行。 让我们看看最后一条语句的实际执行计划向我们展示了什么:

查询执行计划

执行计划显示了该语句的数据行数从 tblCdbG2 表中提取的行数等于 807 行,而不是 63582

在我看来,从 tblCdbG2 中提取的行数必须是 63582。应用 @ItemList 内部联接后,行数必须为 807

在内连接之前显示已过滤的行数的原因是什么?

更新

我稍微修改了现有查询,计划显示相同的值807

查询:

select G2.A0RID 
         from tblCdbG2 G2 with(nolock)
         inner join @ItemList Items
         on Items.ItemRid = G2.G0RID

计划:

稍微修改了 EXISTS 中的查询

Consider the following situation:

  1. There is an xml that contains data @XmlData
  2. The @XmlData is extracted into a relational table (@ItemList)
  3. A table variable is defined (@Table)
  4. The data extracted from 2 db tables (tblCdbA0 and tblCdbG2) into @Table using exists clause

Here is a code sample:

--1. There is an xml that contains data @XmlData 
declare @XmlData xml = '
<Root>
      <Item rid="522822E251CA11D18F1400A02427D15E" />
</Root>'

--2. The @XmlData is extracted into a relational table (@ItemList)
declare @ItemList table (ItemRid char(32) primary key);
insert into @ItemList(ItemRid)
select Tab.rid
from ( select Item.Rid.value('@rid','char(32)') rid
       from @XmlData.nodes('(/Root)[1]/Item') Item(Rid)) Tab
group by Tab.rid

--3. A table variable is defined (@table)
declare @Table TABLE 
(
    Rid char(32) primary key
   ,Rid1 char(32)
   ,Rid2 char(32)
)

--4. The data extracted from 2 db tables (tblCdbA0 and tblCdbG2) into @Table using exists clause
insert into @Table(Rid,Rid1,Rid2)
select A0.A0RID, A0.T4RID, A0.T6RID
from tblCdbA0 A0 with (nolock)
where 
exists (select null 
         from tblCdbG2 G2 with(nolock)
         inner join @ItemList Items
         on Items.ItemRid = G2.G0RID 
         where A0.A0RID=G2.A0RID)

The table tblCdbG2 contains 63582 rows.
Let's look what actual execution plan of the last statement shows us:

Query execution plan

The execution plan shows that number of data rows that are extracted from tblCdbG2 table equal to 807 rows instead of 63582.

In my view, the number of rows that are extracted from tblCdbG2 must be 63582. After inner join with @ItemList is applied the number of rows must be 807.

What is the reason to show already filtered rows number before inner join?

Update:

I have slightly modified the existing query and the plan shows the same value 807.

The query:

select G2.A0RID 
         from tblCdbG2 G2 with(nolock)
         inner join @ItemList Items
         on Items.ItemRid = G2.G0RID

The plan:

Slightly modified query in EXISTS

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仲春光 2024-12-03 22:19:31

左侧的嵌套循环正在从@ItemList 中提取每一行。对于 @Item 列表中的每一行,它使用索引(聚集索引查找)来查找 tblCdbG2 中的匹配行。它不会首先提取所有 60+K 行。

The nested loop to left is pulling every row from @ItemList. For each row from @Item list it is using an index (Clustered Index Seek) to find just the matching row(s) in tblCdbG2. It does not first extract all 60+K rows.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文