2015-09-18 2 views
0

В SQL Server 2012 у меня есть таблица с 1 строкой, которая содержит столбец XML - XMLdata. Размер XML составляет около 10 МБ. Я написал запрос, но выполнение занимает около 1 часа. Существуют ли какие-либо варианты перезаписи запроса, чтобы он работал быстрее?SQL Server: оптимизировать TSQL-запрос с помощью XQuery

Структура XML:

<Settings> 
    <Group Name="A"> 
     <Group Name="AA"> 
      <Group Name="AAA"> 
       <Parameter Name="aaa"> 
        <Value>test1</Value> 
        <Items> 
          <Item Index="0" Name="A"/> 
          <Item Index="1" Name="B"/> 
        </Items> 
       </Parameter> 
      </Group> 
     </Group> 
    </Group> 
</Settings> 

Запрос:

SELECT 
    A.B.value('../../../../../@Name', 'nvarchar(100)') + '/' + A.B.value('../../../../@Name', 'nvarchar(100)') + '/' + A.B.value('../../../@Name', 'nvarchar(100)') AS BlockPath 
    , A.B.value('../../@Name', 'nvarchar(100)') AS ParameterName 
    , A.B.value('./@Index', 'nvarchar(100)') AS ItemIndex 
    , A.B.value('./@Name', 'nvarchar(100)') AS ItemName 
FROM 
    [table] 
CROSS APPLY 
    XMLdata.nodes('//Item') AS A(B); 
+2

Пробовал ли вы искать индексы xml? https://msdn.microsoft.com/en-us/library/bb934097.aspx –

+0

Благодарим за предложение. Я быстро увеличил производительность. –

ответ

3

Попробуйте использовать более сосредоточены XPath, а не заведомо неэффективного //Items подхода.

Я попытался это и получить те же результаты, и более высокая производительность:

SELECT 
    BlockPath = XC.value('../../../@Name', 'nvarchar(100)') + '/' + XC.value('../../@Name', 'nvarchar(100)') + '/' + XC.value('../@Name', 'nvarchar(100)'), 
    ParameterName = XC.value('@Name', 'varchar(100)'), 
    ItemIndex = XCItem.value('@Index', 'int'), 
    ItemName = XCItem.value('@Name', 'varchar(100)') 
FROM 
    [table] 
CROSS APPLY 
    XMLdata.nodes('/Settings/Group/Group/Group/Parameter') AS XT(XC) 
CROSS APPLY 
    XC.nodes('Items/Item') AS XT2(XCItem); 

Первого CROSS APPLY получает <Parameter> узлов - но с прямым XPath с любым // внутри него - а затем второй CROSS APPLY получает узлов Items/Item под каждым узлом <Parameter>.

Попробуйте это - сколько улучшения вы получите?

+0

Я использовал 'SELECT TOP 100' с моим кодом и кодом. Мой код занял 78 секунд, а ваш код - 47 секунд. Это лучше, но все же замедлить. –

+0

Я добавил первичные и вторичные индексы XML, и я быстро увеличил производительность. Для выполнения команды SELECT TOP 100 требуется 3 секунды. –

+0

@AljPra: Хорошо, приятно слушать. Мой опыт работы с индексами XML был менее благоприятным - они ускорили XQuery, но они также раздули мою базу данных примерно с 1,5 ГБ до размера около 11 ГБ ..... –

1

Как указано в комментариях, полезно создать XML Index в вашей колонке. Вы также можете запросить свое поле XML в качестве предлагаемого marc_s. Сочетание этих двух должно дать вам огромный прирост производительности.

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

  • Нет связанных вопросов^_^