Проблема производительности с перекрестным применением при чтении узлов XML для большого набора данных

Проблема с производительностью при перекрестном применении XML:

DataTable имеет 1300 записей, а поле xmldata имеет 250 узлов, поэтому запрос выполняется 1300 * 250 раз, чтобы получить результат, а время выполнения занимает некоторое время... около часа для создания 325000 строк. Кто-нибудь сталкивается с подобной проблемой с большим набором данных? Ваша помощь высоко ценится.

Пример XML:

<dataModel>
  <Colum1>
    <value />
    <displayText />
    <controltype>textbox</controltype>
    <label>Field1</label>
    <controlid>4458575-b0d3-ff4d-01ac-5447e21234dd</controlid>
  </Colum1>
  <Colum2>
    <value />
    <displayText />
    <controltype>textbox</controltype>
    <label>Field2</label>
    <controlid>5a5b7b7e-7b66-1f0d-a562-9d0660a74e11</controlid>
  </Colum2>
....
</dataModel>

select  t.c.value('(local-name(.))[1]', 'nvarchar(100)') as keyname ,
        t.c.value('(controlid)[1]', 'nvarchar(200)') as controlid,
        t.c.value('(label)[1]', 'nvarchar(500)') as label
from DataTable xmldata 
CROSS APPLY xmldata .nodes('/dataModel/*') T(c)

Спасибо


person RMN    schedule 14.05.2020    source источник
comment
Непонятно, о какой платформе или приложении вы спрашиваете. Попробуйте изменить свой вопрос, чтобы включить более конкретные детали.   -  person Jim Riordan    schedule 15.05.2020


Ответы (1)


Ваш подход кажется довольно прямым. Не так много места для улучшений...

Ниже приведено небольшое изменение, но оно может ускорить процесс:

declare @tbl TABLE(ID INT IDENTITY, xmldata XML);
INSERT INTO @tbl VALUES
(N'<dataModel>
  <Colum1>
    <value />
    <displayText />
    <controltype>textbox</controltype>
    <label>Field1</label>
    <controlid>4458575-b0d3-ff4d-01ac-5447e21234dd</controlid>
  </Colum1>
  <Colum2>
    <value />
    <displayText />
    <controltype>textbox</controltype>
    <label>Field2</label>
    <controlid>5a5b7b7e-7b66-1f0d-a562-9d0660a74e11</controlid>
  </Colum2>
</dataModel>');

select  t.c.value('(local-name(.))[1]', 'nvarchar(100)') as keyname ,
        t.c.value('(controlid/text())[1]', 'nvarchar(200)') as controlid,
        t.c.value('(label/text())[1]', 'nvarchar(500)') as label
from @tbl xmldata 
CROSS APPLY xmldata .nodes('/dataModel/*') T(c);

Я добавил /text() к вашим XPath (см. подробности здесь).

Было бы любезно рассказать нам, с какой разницей вы столкнулись при использовании /text(), спасибо.

И важно знать: одна очень дорогая часть XML — это первоначальный синтаксический анализ. Убедитесь, что столбец таблицы изначально типизирован в формате xml и что ваши измерения во время выполнения не искажаются какими-либо действиями по загрузке/чтению/анализу (найдите подробности здесь).

person Shnugo    schedule 15.05.2020
comment
Спасибо Shnugo, Очень ценю ваш ответ. - person RMN; 22.06.2020