SQL: Optymalizacja pracy z kolumnami typu XML – indeksy XML

28-sty-2017

Już od wersji SQL 2005 można w tabelach przechowywać dane w kolumnach o typie XML. Dane tam umieszczone mogą być krótkim fragmentem XML, ale równie dobrze może się tam znajdować obszerny dokument sięgający rozmiarem do 2 GB. To sporo! I co tu zrobić jeśli użytkownik chce wyświetlić tylko te rekordy które w polu XML mają okeśloną wartość? Bez dodatkowych indeksów trzebaby było po prostu przejrzeć wszystkie rekordy i dla każdego z nich oddzielnie analizować XML czy spełnia warunki czy nie. W przypadku dużych dokumentów będzie to ekstremalnie nieefektywne i dlatego właśnie wymyślono indeksy na kolumnach typu XML.

Istnieją dwa rodzaje indeksów XML:

  • PRIMARY
  • SECONDARY

PRIMARY indeks to miejsce w którym składowany jest XML w już przetworzonej postaci. Zauważ, że przechowywanie XML w kolumnie tabeli powoduje, że dane te są nadal podzielone na rekordy. Jeśli więc stworzysz zapytanie, które będzie miało pobrać tylko niektóre rekordy, spełniające określone warunki, to trzeba by było przetwarzać wszystkie dane z wszystkich rekordów, a tego chcemy uniknąć. Dlatego indeks PRIMARY to właśnie miejsce, którym składowany jest sparsowany i przetworzony XML. XML jest już tutaj podzielony na tagi (znaczniki), wartości wyrażone w elementach i atrybutach, ścieżki opisujące jak te wartości były zagnieżdżone w XML. Jeśli pewne pozycje tego PRIMARY indeksu zostaną w jakiś sposób odnalezione (a o tym już za chwilę), to w indeksie PRIMARY znajdzie się klucz podstawowy do podstawowej tabeli, czyli już do właściwego szukanego rekordu. Aby zacząć tworzyć kolejne indeksy SECONDARY musi najpierw istnieć indeks PRIMARY a tabela musi posiadać klucz podstawowy. Mając indeks PRIMARY można już lokalizować obiekty odpowiadające np. następującym wyrażeniom:

  • //ContactRecord/PhoneNumber
  • /Book/*/Title

PRIMARY indeks jest niestety nadal dość ogólny i dlatego mamy indeksy SECONDARY, które ułatwiają wyszukiwanie rekordów zawierających określone wartości, ścieżki i właściwości.  Te indeksy są już dość wyspecjalizoawne. W zależności od tego jaki rodzaj zapytań mają one obsługiwać można utworzyć indeksy następujacych typów:

  • PATH – jeślli zapytania wykorzystują wyrażenia path, w szczególności sprawdzają istnieie pewnej wartości za pomocą funkcji exists(), np. /root/Location lub /root/Location/@LocationID[.=”10″]
  • PROPERTY- jeśli zapytania mają na celu pobranie pewnych wartości z XML, do czego zresztą również można wykorzystywać path expression. Najczęściej zostanie on wybrany jeżeli w zapytaniu skorzystasz z funkcji value()
  • VALUE – jeśli zapytania muszą przeszukiwać kolumnę typu XML w celu znalezienia tych elementów, które mają okeślone atrybuty lub gdy nie jest znane dokładne położenie poszukiwanego elementu w hirarchii elementów, np.  //author[last-name=”Howard”] lub /book [@* = „novel”]

Oto polecenia tworzące PRIMARY XML INDEX a następnie SECONDARY XML INDEXES na kolumnie Demographics w tabeli Person.Person. Zauważ, że tworząc indeks secondary należy powołać się na już wcześniej utworzony indeks PRIMARY:

--First a primary XML index is required
CREATE PRIMARY XML INDEX PXML_Person_Demographics ON Person.Person(Demographics)
GO
--secondary indexes - PATH
CREATE XML INDEX XMLPATH_Person_Demographics ON Person.Person(Demographics)
USING XML INDEX PXML_Person_Demographics FOR PATH
GO
-- PROPERTY
CREATE XML INDEX XMLPROPERTY_Person_Demographics ON Person.Person(Demographics)
USING XML INDEX PXML_Person_Demographics FOR PROPERTY
GO
--VALUE
CREATE XML INDEX XMLVALUE_Person_Demographics ON Person.Person(Demographics)
USING XML INDEX PXML_Person_Demographics FOR VALUE
GO

Komentarze są wyłączone

Autor: Rafał Kraik