2013-07-09 5 views
0

У меня есть SP с частью кода разбора XML-переменных.Сохраненная процедура XML-анализ синтаксиса

XML-имеет следующую структуру:

<root> 
    <ID Reason="1">1</ID> 
    <ID Reason="2">2</ID> 
    <ID Reason="2">3</ID> 
    <ID Reason="1">5</ID> 
</root> 

SP часть кода:

INSERT INTO #tmp_table (ID,Reason) 
SELECT IDs.ID.value('.', 'int') 
    , IDs.ID.value('@Reason', 'int') 
FROM @I_XML.nodes('/root/ID') AS Ids(ID) 

При попытке запустить SP с входным параметром XML, что есть 100000 строк требуется безумное количество времени а стоимость исполнения - 5%.

Как я могу улучшить часть кода SP, чтобы сделать ее быстрее?

+0

Если XML выглядит так, есть ли причина, по которой вызывающий объект не может передать табличный параметр? –

+0

Нет, я не могу изменить тип входного параметра –

+1

Я бы не стал беспокоиться о стоимости исполнения, но «сумасшедшее количество времени» звучит как бы серьезный. Сколько времени на самом деле? В тестах, которые я сделал на ноутбуке, ваш запрос занял 2 секунды, а с переписью в моем ответе потребовалось 1,5 секунды. Версия OPENXML заняла 4 секунды. –

ответ

0

Попробуйте использовать OPENXML:

declare @hXml int 

exec sp_xml_preparedocument @hXml output, @YourXmlParam 

insert into #tmp_table 
select ID, Reason 
from OPENXML(@hXml, '/root/ID') with (ID int '.', Reason int '@Reason') 

exec sp_xml_removedocument @hXml 
+0

Это синтаксис Sql Server 2000, который был заменен в 2005 году. – granadaCoder

+0

Он не был заменен и по-прежнему действителен ([даже в 2012 году] (http://msdn.microsoft.com/en-us/library/ms186918%28v=sql 0,110% 29.aspx)). В некоторых случаях это быстрее, чем использование 'nodes()' и 'value()', но в этом случае я не уверен. –

+0

Хорошо, «заменить» было неправильным словом, я думаю. «Обновлено» и «сохранено для обратной совместимости». Но вы правы, каждый так часто вы можете найти случай, когда он лучше работает только на основе структуры и размера xml. – granadaCoder

2

Вы могли бы попытаться изменить то, как вы запрашиваете значения узлов.

INSERT INTO #tmp_table (ID,Reason) 
SELECT IDs.ID.value('text()[1]', 'int') 
    , IDs.ID.value('@Reason', 'int') 
FROM @I_XML.nodes('/root/ID') AS Ids(ID) 

Указав text() узел вы получите немного другой план выполнения без изменения результата. Используя только имя узла (. в вашем случае), SQL Server сделает глубокий поиск всех значений узлов в указанном узле. В вашем XML нет ни одного, поэтому результат будет таким же.

+0

Нужно ли добавлять текст() для @Reason? Нет? –

+0

@Aleksandr Нет, атрибут - только значения singel и не может быть родительским узлом для других узлов. –

Смежные вопросы