T-SQL запрашивает столбец XML с XPath очень медленно - как улучшить, или альтернативы? - PullRequest
3 голосов
/ 11 ноября 2010

У меня есть таблица, которая содержит столбец типа данных XML.Прямо сейчас подход заключается в использовании XPath для запроса значений, которые находятся в XML.К сожалению, этот метод оказывается очень медленным.

В таблице около 500 000 строк.На самом деле это промежуточная таблица, которая получает новые данные каждый день, поэтому применение индексации XML к столбцу нецелесообразно - ежедневная операция INSERT тогда занимает несколько часов.Без индексации оно завершается примерно через минуту.

Есть ли альтернативы для запроса этих данных XML, которые были бы намного быстрее?

Ответы [ 2 ]

7 голосов
/ 11 ноября 2010

Сколько элементов внутри XML нужно запрашивать на регулярной основе ??Всего несколько ??

Решение, которое мы выбрали для решения тех же проблем, заключается в следующем:

  • создать хранимую функцию, которая принимает параметр XML в качестве входных данных
  • в этой функции извлеките необходимую информацию из XML с помощью XQuery / XPath
  • создайте вычисляемый постоянный столбец в вашей таблице, который ссылается на эту функцию

Таким образом, мы вытаскиваем три, четыре наиболее часто используемых элемента информации (в нашем случае часто это просто INT) и делаем их доступными в виде столбцов на базовой таблице.Поскольку они сохраняются, они не будут пересчитываться при каждом доступе - только при изменении содержимого XML;а также, поскольку они сохраняются, вы можете при необходимости добавить к ним обычный некластеризованный индекс.

Пример:

у нас есть функция, которая извлекает BIT из XML и сообщает нам,или у данного контракта нет VPN-соединения или нет:

CREATE FUNCTION dbo.GetVPNFlag(@Data XML)
RETURNS BIT
WITH SCHEMABINDING
AS BEGIN
  DECLARE @VPNFlag BIT

  SELECT  
    @VPNFlag = ISNULL(@Data.value('(EntryIP/VPNOption)[1]', 'bit'), 0)

  RETURN @VPNFlag
END

При наличии XML-кода это выберет флаг VPN и вернет его.Затем мы создали вычисляемый постоянный столбец в нашей базовой таблице:

ALTER TABLE dbo.ContractData
  ADD IsVPN AS dbo.GetVPNFlag(XmlData) PERSISTED

Здесь мы передаем содержимое XmlData из таблицы ContractData в функцию.Мы получаем BIT, который хранится как столбец IsVPN в таблице ContractData.

Теперь мы можем легко получить все контракты с VPN, например:

SELECT (list of fields) 
FROM dbo.ContractData
WHERE IsVPN = 1
0 голосов
/ 11 ноября 2010

У нас была та же ситуация и объем данных, и после настройки в итоге появился триггер вставки и обновления, вставляющий данные в «таблицы хранилища данных». Это дает более медленную вставку, но выполнимо для наших пользователей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...