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

时间:2011-07-28 12:54:50

标签: sql sql-server sql-server-2008 sql-execution-plan

考虑以下情况:

  1. 有一个包含数据@XmlData
  2. 的xml
  3. 将@XmlData提取到关系表(@ItemList)
  4. 定义了一个表变量(@Table)
  5. 使用exists子句从2个db表(tblCdbA0和tblCdbG2)中提取到@Table的数据
  6. 以下是代码示例:

    --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 行。 让我们看看最后一个语句的实际执行计划向我们展示了什么:

    Query execution plan

    执行计划显示从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
    

    计划:

    Slightly modified query in EXISTS

1 个答案:

答案 0 :(得分:2)

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