Что быстрее .exist или .value в предложении where? - PullRequest
6 голосов
/ 27 мая 2011

Я выполняю некоторые грубые тесты с типом данных xml SQL Server 2008. Я видел много мест, где .exist используется в предложениях where.Недавно я сравнил два запроса и получил странные результаты.

select count(testxmlrid) from testxml
where Attributes.exist('(form/fields/field)[@id="1"]')=1

Выполнение этого запроса занимает около 1,5 секунд, без индексов ни для чего, кроме первичного ключа (testxmlrid)

select count(testxmlrid) from testxml
where Attributes.value('(/form/fields/field/@id)[1]','integer')=1

С другой стороны, этот запрос занимает около 0,75запустить.

Я использую нетипизированный XML, и мой тест проводится на экземпляре SQL Server 2008 Express.В наборе данных содержится около 15 000 строк, а каждая строка XML имеет длину около 25 строк.

Эти результаты я получаю правильно?Если так, то почему все используют .exist?Я делаю что-то не так, и .exist может быть быстрее?

Ответы [ 2 ]

3 голосов
/ 27 мая 2011

Ты не считаешь одно и то же. Ваш .exist запрос (form/fields/field)[@id="1"] проверяет все вхождения @id в XML, пока не найдет его со значением 1, а ваш .value запрос (/form/fields/field/@id)[1] извлекает только первое вхождение @id.

Проверьте это:

declare @T table
(
  testxmlrid int identity primary key,
  Attributes xml
)

insert into @T values
('<form>
    <fields>
      <field id="2"/>
      <field id="1"/>
    </fields>
  </form>')

select count(testxmlrid) from @T
where Attributes.exist('(form/fields/field)[@id="1"]')=1

select count(testxmlrid) from @T
where Attributes.value('(/form/fields/field/@id)[1]','integer')=1

Количество запросов .exist равно 1, поскольку он находит @id=1 во втором узле field, а число запросов .value равно 0, поскольку он проверяет только значение для первого вхождения @id.

Запрос .exist, который проверяет только значение для первого вхождения @id, как ваш запрос .value будет выглядеть следующим образом.

select count(testxmlrid) from @T
where Attributes.exist('(/form/fields/field/@id)[1][.="1"]')=1
0 голосов
/ 27 мая 2011

Разница может исходить из ваших индексов.

Индекс PATH повысит производительность предиката exist() в предложении WHERE, тогда как индекс PROPERTY повысит производительность функции value().

Читать: http://msdn.microsoft.com/en-us/library/bb522562.aspx

...