Udostępnij za pośrednictwem


Określanie ścieżek i wskazówek optymalizacji dla selektywnych indeksów XML

Dotyczy:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

W tym artykule opisano sposób określania ścieżek węzłów do indeksowania i wskazówek optymalizacji dotyczących indeksowania podczas tworzenia lub zmieniania selektywnych indeksów XML.

Ścieżki węzłów i wskazówki optymalizacji są określane jednocześnie w jednej z następujących instrukcji:

Aby uzyskać więcej informacji na temat selektywnych indeksów XML, zobacz Selektywne indeksy XML (SXI).

Informacje o typach XQuery i SQL Server w nietypowym formacie XML

Selektywne indeksy XML obsługują dwa systemy typów: typy XQuery i typy programu SQL Server. Ścieżka indeksowana może służyć do dopasowania wyrażenia XQuery lub do dopasowania typu zwracanego metody value() typu danych xml.

  • Gdy ścieżka do indeksu nie jest oznaczona adnotacją lub jest oznaczona słowem kluczowym XQUERY, ścieżka odpowiada wyrażeniu XQuery. Są dwa warianty ścieżek węzłów zaopatrzonych w adnotacje XQUERY.

    • Jeśli nie określisz słowa kluczowego XQUERY i typu danych XQuery, zostaną użyte domyślne mapowania. Zazwyczaj wydajność i pamięć nie są optymalne.

    • Jeśli określisz słowo kluczowe XQUERY i typ danych XQuery oraz opcjonalnie inne wskazówki dotyczące optymalizacji, możesz uzyskać najlepszą możliwą wydajność i najbardziej wydajny magazyn. Jednak rzutowanie może zakończyć się niepowodzeniem.

  • Gdy ścieżka do indeksu jest oznaczona adnotacją ze słowem kluczowym SQL, ścieżka jest zgodna z typem zwrotnym metody value() typu danych xml. Określ odpowiedni typ danych programu SQL Server, czyli typ zwracany, którego oczekujesz od metody value().

Istnieją subtelne różnice między systemem typów XML wyrażeń XQuery a systemem typów programu SQL Server zastosowanym do metody value() typu danych xml. Te różnice obejmują następujące kwestie:

  • System typów XQuery rozpoznaje końcowe spacje. Na przykład, zgodnie z semantyka typów XQuery, ciągi "abc" i "abc " nie są równe, podczas gdy w programie SQL Server te ciągi są równe.

  • Typy danych zmiennoprzecinkowych XQuery obsługują specjalne wartości +/- zero i +/- nieskończoność. Te wartości specjalne nie są obsługiwane w typach danych zmiennoprzecinkowych programu SQL Server.

Typy XQuery w nietypowanym XML

  • Typy XQuery pasują do wyrażeń XQuery we wszystkich metodach xml typu danych, w tym metody value().

  • Typy XQuery obsługują następujące wskazówki optymalizacji: node(), SINGLETON, DATA TYPE i MAXLENGTH.

W przypadku wyrażeń XQuery dla nietypowanego XML można wybrać między dwoma trybami działania.

  • domyślny tryb mapowania. W tym trybie należy określić tylko ścieżkę podczas tworzenia selektywnego indeksu XML.

  • tryb mapowania określony przez użytkownika. W tym trybie należy określić zarówno ścieżkę, jak i opcjonalne wskazówki optymalizacji.

Domyślny tryb mapowania używa konserwatywnej opcji przechowywania, która jest zawsze bezpieczna i ogólna. Może być zgodny z dowolnym typem wyrażenia. Ograniczenie domyślnego trybu mapowania jest mniejsze niż optymalna wydajność, ponieważ wymagana jest zwiększona liczba rzutów w czasie wykonywania, a indeksy pomocnicze nie są dostępne.

Oto przykład selektywnego indeksu XML utworzonego z domyślnymi mapowaniami. Dla wszystkich trzech ścieżek używany jest domyślny typ węzła (xs:untypedAtomic) i kardynalność.

CREATE SELECTIVE XML INDEX example_sxi_UX_default
ON Tbl(xmlcol)
FOR
(
    mypath01 =  '/a/b',
    mypath02 = '/a/b/c',
    mypath03 = '/a/b/d'
);

Tryb mapowania określony przez użytkownika umożliwia określenie typu i kardynalności węzła w celu uzyskania lepszej wydajności. Jednak ta poprawa wydajności jest osiągana przez rezygnację z bezpieczeństwa — ponieważ rzutowanie może zakończyć się niepowodzeniem — i uogólnienie — ponieważ tylko określony typ jest zgodny z selektywnym indeksem XML.

Typy XQuery obsługiwane w przypadku nietypowych przypadków XML to:

  • xs:boolean
  • xs:double
  • xs:string
  • xs:date
  • xs:time
  • xs:dateTime

Jeśli typ nie jest określony, przyjmuje się, że węzeł ma być typu danych xs:untypedAtomic.

Możesz zoptymalizować selektywny indeks XML pokazany w następujący sposób:

CREATE SELECTIVE XML INDEX example_sxi_UX_optimized
ON Tbl(xmlcol)
FOR
(
    mypath= '/a/b' as XQUERY 'node()',
    pathX = '/a/b/c' as XQUERY 'xs:double' SINGLETON,
    pathY = '/a/b/d' as XQUERY 'xs:string' MAXLENGTH(200) SINGLETON
);
-- mypath - Only the node value is needed; storage is saved.
-- pathX - Performance is improved; secondary indexes are possible.
-- pathY - Performance is improved; secondary indexes are possible; storage is saved.

Typy programu SQL Server w nietypowym formacie XML

  • Typy programu SQL Server są zgodne z wartością zwracaną metody value().

  • Typy programu SQL Server obsługują tę wskazówkę optymalizacji: SINGLETON.

Określenie typu jest obowiązkowe dla ścieżek, które zwracają typy programu SQL Server. Użyj tego samego typu programu SQL Server, którego należy użyć w metodzie value().

Rozważ następujące zapytanie:

SELECT T.record,
    T.xmldata.value('(/a/b/d)[1]', 'NVARCHAR(200)')
FROM myXMLTable T;

Określone zapytanie zwraca wartość ze ścieżki /a/b/d spakowane do typu danych NVARCHAR(200), więc typ danych do określenia dla węzła jest oczywisty. Nie ma jednak schematu określającego kardynalność węzła w nietypowym pliku XML. Aby określić, że węzeł d pojawia się co najwyżej raz w obszarze węzła nadrzędnego b, utwórz selektywny indeks XML, który używa wskazówki optymalizacji SINGLETON w następujący sposób:

CREATE SELECTIVE XML INDEX example_sxi_US
ON Tbl(xmlcol)
FOR
(
    node1223 = '/a/b/d' as SQL NVARCHAR(200) SINGLETON
);

Opis obsługi selektywnego indeksu XML dla typizowanego kodu XML

Typowany kod XML w programie SQL Server jest schematem skojarzonym z danym dokumentem XML. Schemat definiuje ogólną strukturę dokumentów i typy węzłów. Jeśli istnieje schemat, selektywny indeks XML stosuje strukturę schematu, gdy użytkownik promuje ścieżki, więc nie ma potrzeby określania typów XQUERY dla ścieżek.

Selektywny indeks XML obsługuje następujące typy XSD:

  • xs:anyUri
  • xs:boolean
  • xs:date
  • xs:dateTime
  • xs:day
  • xs:decimal
  • xs:double
  • xs:float
  • xs:int
  • xs:integer
  • xs:language
  • xs:long
  • xs:name
  • xs:NCName
  • xs:negativeInteger
  • xs:nmtoken
  • xs:nonNegativeInteger
  • xs:nonPositiveInteger
  • xs:positiveInteger
  • xs:qname
  • xs:short
  • xs:string
  • xs:time
  • xs:token
  • xs:unsignedByte
  • xs:unsignedInt
  • xs:unsignedLong
  • xs:unsignedShort

Po utworzeniu selektywnego indeksu XML na dokumencie, który ma skojarzony schemat, określenie typu XQuery podczas tworzenia lub zmiany indeksu zwraca błąd. Użytkownik może używać adnotacji typu SQL w części promocji ścieżki. Typ SQL musi być prawidłową konwersją z typu XSD zdefiniowanego w schemacie lub zgłaszany jest błąd. Obsługiwane są wszystkie typy SQL, które mają odpowiednią reprezentację w XSD, z wyjątkiem typów daty/godziny.

Notatka

Indeks selektywny jest używany, jeśli typ określony w promowaniu ścieżki indeksu selektywnego XML jest taki sam jak wartość zwracana przez metodę value().

Następujące wskazówki optymalizacji mogą być używane z wpisanymi dokumentami XML:

  • node() wskazówka optymalizacji.

  • Wskazówka optymalizacji MAXLENGTH może być używana z typami xs:string w celu skrócenia indeksowanej wartości.

Aby uzyskać więcej informacji na temat wskazówek dotyczących optymalizacji, zobacz Określanie wskazówek optymalizacji.

Określanie ścieżek

Selektywny indeks XML umożliwia indeksowanie tylko podzestawu węzłów z przechowywanych danych XML, które są istotne dla zapytań, które mają być uruchamiane. Gdy podzestaw odpowiednich węzłów jest znacznie mniejszy niż całkowita liczba węzłów w dokumencie XML, selektywny indeks XML przechowuje tylko odpowiednie węzły. Aby skorzystać z selektywnego indeksu XML, zidentyfikuj prawidłowy podzbiór węzłów do indeksowania.

Wybieranie węzłów do indeksowania

Poniższe dwie zasady umożliwiają zidentyfikowanie prawidłowego podzestawu węzłów w celu dodania do selektywnego indeksu XML.

  1. zasada 1: aby ocenić dane wyrażenie XQuery, zaindeksuj wszystkie węzły, które należy zbadać.

    • Indeksuj wszystkie węzły, których istnienie lub wartość jest używane w wyrażeniu XQuery.

    • Indeksowanie wszystkich węzłów w wyrażeniu XQuery, na którym są stosowane predykaty XQuery.

    Rozważ następujące zapytanie dotyczące przykładowego dokumentu XML w tym artykule:

    SELECT T.record FROM myXMLTable T
    WHERE T.xmldata.exist('/a/b[./c = "43"]') = 1;
    

    Aby zwrócić wystąpienia XML, które spełniają to zapytanie, selektywny indeks XML musi zbadać dwa węzły w każdym wystąpieniu XML:

    • Węzeł c, ponieważ jego wartość jest używana w wyrażeniu XQuery.

    • Węzeł b, ponieważ predykat jest stosowany za pośrednictwem węzłab w wyrażeniu XQuery.

  2. zasada 2: aby uzyskać najlepszą wydajność, indeksuj wszystkie węzły wymagane do oceny danego wyrażenia XQuery. Jeśli indeksujesz tylko niektóre węzły, selektywny indeks XML poprawia ocenę podexpressionów, które obejmują tylko węzły indeksowane.

Aby poprawić wydajność powyższej instrukcji SELECT, możesz utworzyć następujący selektywny indeks XML:

CREATE SELECTIVE XML INDEX simple_sxi
ON Tbl(xmlcol)
FOR
(
    path123 =  '/a/b',
    path124 =  '/a/b/c'
);

Indeksowanie identycznych ścieżek

Nie można promować identycznych ścieżek jako tego samego typu danych pod różnymi nazwami ścieżek. Na przykład następujące zapytanie zgłasza błąd, ponieważ pathOne i pathTwo są identyczne:

CREATE SELECTIVE INDEX test_simple_sxi ON T1(xmlCol)
FOR
(
    pathOne = 'book/authors/authorID' AS XQUERY 'xs:string',
    pathTwo = 'book/authors/authorID' AS XQUERY 'xs:string'
);

Można jednak promować identyczne ścieżki jako różne typy danych, nadając im różne nazwy. Na przykład następujące zapytanie jest teraz akceptowalne, ponieważ typy danych są różne:

CREATE SELECTIVE INDEX test_simple_sxi ON T1(xmlCol)
FOR
(
    pathOne = 'book/authors/authorID' AS XQUERY 'xs:double',
    pathTwo = 'book/authors/authorID' AS XQUERY 'xs:string'
);

Przykłady

Poniżej przedstawiono kilka innych przykładów wybierania odpowiednich węzłów do indeksowania dla różnych typów XQuery.

Przykład 1

Oto prosta metoda XQuery korzystająca z metody exist():

SELECT T.record FROM myXMLTable T
WHERE T.xmldata.exist('/a/b/c/d/e/h') = 1;

W poniższej tabeli przedstawiono węzły, które powinny być indeksowane, aby umożliwić temu zapytaniu użycie selektywnego indeksu XML.

Węzeł do uwzględnienia w indeksie Przyczyna indeksowania tego węzła
/a/b/c/d/e/h Istnienie węzła h jest oceniane w metodzie exist().

Przykład 2

Oto bardziej złożona odmiana poprzedniego zapytania XQuery z zastosowanym predykatem:

SELECT T.record FROM myXMLTable T
WHERE T.xmldata.exist('/a/b/c/d/e[./f = "SQL"]') = 1;

W poniższej tabeli przedstawiono węzły, które powinny być indeksowane, aby umożliwić temu zapytaniu użycie selektywnego indeksu XML.

Węzeł do uwzględnienia w indeksie Przyczyna indeksowania tego węzła
/a/b/c/d/e Predykat jest stosowany za pośrednictwem węzła e.
/a/b/c/d/e/f Wartość węzła f jest oceniana wewnątrz predykatu.

Przykład 3

Oto bardziej złożone zapytanie z klauzulą value():

SELECT T.record,
    T.xmldata.value('(/a/b/c/d/e[./f = "SQL"]/g)[1]', 'nvarchar(100)')
FROM myXMLTable T;

W poniższej tabeli przedstawiono węzły, które powinny być indeksowane, aby umożliwić temu zapytaniu użycie selektywnego indeksu XML.

Węzeł do uwzględnienia w indeksie Przyczyna indeksowania tego węzła
/a/b/c/d/e Predykat jest zastosowany dla węzła e.
/a/b/c/d/e/f Wartość węzła f jest oceniana wewnątrz predykatu.
/a/b/c/d/e/g Wartość g węzła jest zwracana przez metodę value().

Przykład 4

Oto zapytanie, które używa klauzuli FLWOR wewnątrz klauzuli exist(). (Nazwa FLWOR pochodzi z pięciu klauzul, które mogą składać się na wyrażenie XQuery FLWOR: for, let, where, order by i return.)

SELECT T.record FROM myXMLTable T
WHERE T.xmldata.exist('
  For $x in /a/b/c/d/e
  Where $x/f = "SQL"
  Return $x/g
') = 1;

W poniższej tabeli przedstawiono węzły, które powinny być indeksowane, aby umożliwić temu zapytaniu użycie selektywnego indeksu XML.

Węzeł do uwzględnienia w indeksie Przyczyna indeksowania tego węzła
/a/b/c/d/e Istnienie węzła e jest sprawdzane w klauzuli FLWOR.
/a/b/c/d/e/f Wartość węzła f jest oceniana w klauzuli FLWOR.
/a/b/c/d/e/g Istnienie węzła g oceniane jest metodą exist().

Określanie wskazówek dotyczących optymalizacji

Możesz użyć opcjonalnych wskazówek optymalizacji, aby określić dodatkowe szczegóły mapowania węzła indeksowanego przez selektywny indeks XML. Można na przykład określić typ danych i kardynalność węzła oraz pewne informacje o strukturze danych. Te dodatkowe informacje umożliwiają lepsze mapowanie. Powoduje to również poprawę wydajności, oszczędności w przechowywaniu danych, lub oba.

Użycie wskazówek optymalizacji jest opcjonalne. Zawsze możesz zaakceptować domyślne mapowania, które są niezawodne, ale mogą nie zapewniać optymalnej wydajności i przechowywania.

Niektóre wskazówki dotyczące optymalizacji, takie jak wskazówka SINGLETON, wprowadzają ograniczenia dotyczące danych. W niektórych przypadkach błędy mogą być zgłaszane, gdy te ograniczenia nie zostaną spełnione.

Zalety wskazówek optymalizacji

W poniższej tabeli przedstawiono wskazówki dotyczące optymalizacji, które umożliwiają bardziej efektywne przechowywanie lub lepszą wydajność.

Wskazówka dotycząca optymalizacji Wydajniejszy magazyn Zwiększona wydajność
node() Tak Nie
SINGLETON Nie Tak
TYP DANYCH Tak Tak
MAXLENGTH Tak Tak

Wskazówki dotyczące optymalizacji i typy danych

Węzły można indeksować jako typy danych XQuery lub jako typy danych programu SQL Server. W poniższej tabeli pokazano, które wskazówki optymalizacji są obsługiwane w przypadku każdego typu danych.

Wskazówka dotycząca optymalizacji Typy danych XQuery Typy danych SQL
node() Tak Nie
SINGLETON Tak Tak
TYP DANYCH Tak Nie
MAXLENGTH Tak Nie

wskazówka optymalizacji node()

Dotyczy: typów danych XQuery

Optymalizację node() można użyć do określenia węzła, którego wartość nie jest wymagana do oceny typowego zapytania. Ta wskazówka zmniejsza wymagania dotyczące przechowywania, gdy typowe zapytanie musi jedynie ocenić istnienie węzła. (Domyślnie selektywny indeks XML przechowuje wartość dla wszystkich promowanych węzłów, z wyjątkiem złożonych typów węzłów).

Rozważmy następujący przykład:

SELECT T.record FROM myXMLTable T
WHERE T.xmldata.exist('/a/b[./c=5]') = 1;

Aby użyć selektywnego indeksu XML do oceny tego zapytania, podwyższ poziom węzłów b i c. Jednak ponieważ wartość węzła b nie jest wymagana, można użyć wskazówki node() z następującą składnią:

`/a/b/ as node()

Jeśli zapytanie wymaga wartości węzła indeksowanego za pomocą wskazówki node(), nie można użyć selektywnego indeksu XML.

Wskazówka optymalizacji SINGLETON

dotyczy następujących typów danych XQuery lub SQL Server

Wskazówka optymalizacji SINGLETON określa kardynalność węzła. Ta wskazówka poprawia wydajność zapytań, ponieważ z góry wiadomo, że węzeł pojawia się co najwyżej raz w obrębie swojego rodzica lub przodka.

Weź pod uwagę przykład dokumentu XML w tym artykule.

Aby użyć selektywnego indeksu XML do wykonywania zapytań względem tego dokumentu, możesz określić wskazówkę SINGLETON dla węzła d, ponieważ jest ona wyświetlana najwyżej jeden raz w ramach elementu nadrzędnego.

Jeśli określono wskazówkę SINGLETON, ale węzeł pojawia się więcej niż raz w obrębie swojego rodzica lub przodka, błąd zostanie zgłoszony podczas tworzenia indeksu (dla istniejących danych) lub uruchamiania zapytania (dla nowych danych).

Wskazówka dotycząca optymalizacji typu danych

Dotyczy: typów danych XQuery

Wskazówka optymalizacji typu danych umożliwia określenie typu danych XQuery lub SQL Server dla indeksowanego węzła. Typ danych jest używany dla kolumny w tabeli danych selektywnego indeksu XML, który odpowiada indeksowanemu węzłowi.

W przypadku niepowodzenia rzutowania istniejącej wartości do określonego typu danych operacja wstawiania (do indeksu) nie kończy się niepowodzeniem; jednak wartość null jest wstawiana do tabeli danych indeksu.

MAXLENGTH — wskazówka optymalizacji

Dotyczy: typów danych XQuery

Wskazówka optymalizacji MAXLENGTH umożliwia ograniczenie długości danych xs:string. FUNKCJA MAXLENGTH nie jest odpowiednia dla typów danych programu SQL Server, ponieważ określasz długość podczas określania typów dat VARCHAR lub NVARCHAR.

Jeśli istniejący ciąg jest dłuższy niż określony parametr MAXLENGTH, wstawianie tej wartości do indeksu kończy się niepowodzeniem.

Przykładowy dokument XML dla przykładów

W przykładach w tym artykule odwołuje się następujący przykładowy dokument XML:

<a>
    <b>
         <c atc="aa">10</c>
         <c atc="bb">15</c>
         <d atd1="dd" atd2="ddd">md </d>
    </b>
     <b>
        <c></c>
        <c atc="">117</c>
     </b>
</a>

Zobacz też