考虑以下情况:
以下是代码示例:
--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
计划:
答案 0 :(得分:2)
左边的嵌套循环从@ItemList中拉出每一行。对于@Item列表中的每一行,它使用索引(Clustered Index Seek)来查找tblCdbG2中的匹配行。它不会首先提取所有60 + K行。