Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

кръстосаното прилагане на xml заявката работи експоненциално по-зле с нарастването на xml документа

Какво прави заявката за кръстосано прилагане да се представя толкова лошо в този прост XML документ и експоненциално по-бавна с нарастването на набора от данни?

Това е използването на родителската ос за получаване на идентификатора на атрибута от възела на елемента.

Именно тази част от плана на заявката е проблематична.

Забележете 423-те реда, които излизат от долната функция с таблица.

Добавянето само на още един възел на елемент с три възела на полета ви дава това.

Върнати са 732 реда.

Ами ако удвоим възлите от първата заявка до общо 6 възела на елемента?

Върнахме огромен ред от 1602.

Фигурата 18 в горната функция е всички възли на полето във вашия XML. Тук имаме 6 артикула с три полета във всеки артикул. Тези 18 възела се използват във вложено свързване на цикли срещу другата функция, така че 18 изпълнения, връщащи 1602 реда, дават, че тя връща 89 реда на итерация. Това просто е точният брой възли в целия XML. Е, всъщност е един повече от всички видими възли. не знам защо. Можете да използвате тази заявка, за да проверите общия брой възли във вашия XML.

select count(*)
from @XML.nodes('//*, //@*, //*/text()') as T(X)  

Така алгоритъмът, използван от SQL Server за получаване на стойността, когато използвате родителската ос .. във функцията за стойности е, че тя първо намира всички възли, на които раздробявате, 18 в последния случай. За всеки от тези възли той раздробява и връща целия XML документ и проверява във филтърния оператор за възела, който всъщност искате. Тук имате експоненциален растеж. Вместо да използвате родителската ос, трябва да използвате едно допълнително кръстосано приложение. Първо настържете на артикул и след това на поле.

select I.X.value('@name', 'varchar(5)') as item_name,
       F.X.value('@id', 'uniqueidentifier') as field_id,
       F.X.value('@type', 'int') as field_type,
       F.X.value('text()[1]', 'nvarchar(15)') as field_value
from #temp as T
  cross apply T.x.nodes('/data/item') as I(X)
  cross apply I.X.nodes('field') as F(X)

Също така промених начина, по който осъществявате достъп до текстовата стойност на полето. Използване на . ще накара SQL Server да търси дъщерни възли в field и конкатенирайте тези стойности в резултата. Нямате дъщерни стойности, така че резултатът е същият, но е добре да избягвате да имате тази част в плана на заявката (оператор UDX).

Планът на заявката няма проблем с родителската ос, ако използвате XML индекс, но все пак ще имате полза от промяната на начина, по който извличате стойността на полето.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Създайте свързан сървър в SQL Server (пример за T-SQL)

  2. INSTR() Еквивалент в SQL Server

  3. Динамична въртяща се таблица в SQL Server

  4. Разберете дали даден обект е външен ключ с OBJECTPROPERTY() в SQL Server

  5. Как да коригирате грешка Msg 7325 в SQL Server:„Обекти, излагащи колони с типове CLR, не са разрешени в разпределени заявки“