Какво прави заявката за кръстосано прилагане да се представя толкова лошо в този прост 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 индекс, но все пак ще имате полза от промяната на начина, по който извличате стойността на полето.