SQL Server 2008: план выполнения содержит неверные данные? - PullRequest
2 голосов
/ 28 июля 2011

Рассмотрим следующую ситуацию:

  1. Существует xml, содержащий данные @XmlData
  2. @XmlData извлекается в реляционную таблицу (@ItemList)
  3. Определена табличная переменная (@Table)
  4. Данные, извлеченные из таблиц в 2 дБ (tblCdbA0 и tblCdbG2) в таблицу @Table с использованием существующего предложения

Вот пример кода:

--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 Ответ

2 голосов
/ 28 июля 2011

Вложенный цикл слева вытягивает каждую строку из @ItemList.Для каждой строки из списка @Item он использует индекс (Clustered Index Seek), чтобы найти только соответствующие строки в tblCdbG2.Сначала не извлекаются все 60 + K строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...