선택적 XML 인덱스에 대한 경로 및 최적화 힌트 지정
적용 대상: SQL Server Azure SQL Database Azure SQL Managed Instance
이 문서에서는 선택적 XML 인덱스를 만들거나 변경할 때 인덱싱할 노드 경로 및 인덱싱에 대한 최적화 힌트를 지정합니다.
다음 문 중 하나에서 노드 경로 및 최적화 힌트를 동시에 지정합니다.
CREATE 문의 FOR 절. 자세한 내용은 CREATE SELECTIVE XML INDEX(Transact-SQL)를 참조하세요.
ALTER 문의 ADD 절에서 자세한 내용은 ALTER 인덱스(선택적 XML 인덱스)를 참조하세요.
선택적 XML 인덱스에 대한 자세한 내용은 SXI(선택적 XML 인덱스)를 참조하세요.
형식화되지 않은 XML에서의 XQuery 및 SQL Server 형식 이해
선택적 XML 인덱스는 XQuery 형식 및 SQL Server 형식의 두 가지 형식 시스템을 지원합니다. 인덱싱된 경로를 사용하여 XQuery 식을 일치시키거나 xml 데이터 형식의 value()
메서드의 반환 형식과 일치시킬 수 있습니다.
인덱스할 경로에 주석이 추가되지 않았거나 XQUERY 키워드로 주석이 추가된 경우 경로는 XQuery 식과 일치합니다. XQUERY 주석이 추가된 노드 경로에는 두 가지 변형이 있습니다.
XQUERY 키워드 및 XQuery 데이터 형식을 지정하지 않으면 기본 설정 매핑이 사용됩니다. 일반적으로 성능 및 스토리지는 최적이 아닙니다.
XQUERY 키워드와 XQuery 데이터 형식 및 선택적으로 다른 최적화 힌트를 지정하는 경우 가능한 최상의 성능과 가장 효율적인 스토리지를 달성할 수 있습니다. 하지만, 캐스트는 실패할 수 있습니다.
인덱싱할 경로가 SQL 키워드로 주석이 추가된 경우 해당 경로는 xml 데이터 형식의
value()
메서드의 반환 형식과 일치합니다.value()
메서드에서 예상하는 반환 형식인 적절한 SQL Server 데이터 형식을 지정합니다.
XQuery 식 XML 형식 시스템과 xml 데이터 형식의 value()
메서드에 적용된 SQL Server 형식 시스템 간에는 미묘한 차이가 있습니다. 이러한 차이점은 다음과 같습니다.
XQuery 유형 시스템은 후행 공백을 인식합니다. 예를 들어 XQuery 유형 의미 체계에서는 문자열 "abc"와 "abc "가 같은 문자열이 아니지만 SQL 서버에서 이러한 문자열은 같은 문자열입니다.
XQuery 부동 소수점 데이터 형식에서는 +/- 제로 및 +/- 무한대와 같은 특수 값을 지원합니다. 이러한 특수한 값은 SQL Server 부동 소수점 데이터 형식에서는 지원되지 않습니다.
형식화되지 않은 XML의 XQuery 형식
XQuery 유형은
value()
메서드를 포함한 xml 데이터 형식의 모든 메서드에있는 XQuery 식과 일치합니다.XQuery 유형은 node(), SINGLETON, DATA TYPE 및 MAXLENGTH 최적화 힌트를 지원합니다.
형식화되지 않은 XML에 대한 XQuery 식의 경우 두 가지 작업 모드 중에서 선택할 수 있습니다.
기본 바인딩 모드. 이 모드에서는 선택적 XML 인덱스를 생성할 때의 경로만 지정합니다.
사용자 지정 매핑 모드. 이 모드에서는 경로와 선택적 최적화 힌트 모두를 지정합니다.
기본 매핑 모드는 항상 안전하고 일반적인 보수적 스토리지 옵션을 사용합니다. 모든 식 형식이라도 일치시킬 수 있습니다. 더 많은 런타임 캐스트 수가 필요하고 보조 인덱스를 사용할 수 없기 때문에 기본 매핑 모드의 제한 사항이 최적 성능보다 적습니다.
다음은 기본 매핑을 사용하여 생성한 선택적 XML 인덱스의 예제입니다. 세 경로 모두에 기본 노드 형식(xs:untypedAtomic) 및 카디널리티가 사용됩니다.
CREATE SELECTIVE XML INDEX example_sxi_UX_default
ON Tbl(xmlcol)
FOR
(
mypath01 = '/a/b',
mypath02 = '/a/b/c',
mypath03 = '/a/b/d'
);
사용자 지정 매핑 모드를 사용하면 더 나은 성능을 발휘하기 위해 노드 형식 및 카디널리티를 지정할 수 있습니다. 그러나 캐스팅이 실패할 수 있고 지정된 유형만 선택적 XML 인덱스와 일치하므로 이 향상된 성능은 보안의 희생을 통해 얻어집니다.
형식화되지 않은 XML 사례를 지원하는 XQuery 형식은 다음과 같습니다.
xs:boolean
xs:double
xs:string
xs:date
xs:time
xs:dateTime
형식을 지정하지 않으면 노드는 xs:untypedAtomic
데이터 형식으로 간주됩니다.
다음과 같은 방법으로 선택적 XML 인덱스를 최적화할 수 있습니다.
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.
형식화되지 않은 XML의 SQL Server 형식
SQL Server 형식은
value()
메서드의 반환 값과 일치합니다.SQL Server 형식은 이 최적화 힌트인 SINGLETON을 지원합니다.
SQL Server 형식을 반환하는 경로는 형식을 지정하는 것이 필수입니다. value()
메서드에서 사용하는 것과 동일한 SQL Server 형식을 사용합니다.
다음과 같은 쿼리를 고려해 보세요.
SELECT T.record,
T.xmldata.value('(/a/b/d)[1]', 'NVARCHAR(200)')
FROM myXMLTable T;
지정된 쿼리는 NVARCHAR(200) 데이터 형식으로 압축된 경로 /a/b/d
의 값을 반환하므로 노드에 지정할 데이터 형식이 분명합니다. 하지만, 형식화되지 않은 XML에서 노드의 카디널리티를 지정하는 스키마는 없습니다. d
노드가 해당 부모 노드인 b
에 최대 한 번만 표시되도록 지정하려면 다음과 같이 SINGLETON 최적화 힌트를 사용하는 선택적 XML 인덱스를 만듭니다.
CREATE SELECTIVE XML INDEX example_sxi_US
ON Tbl(xmlcol)
FOR
(
node1223 = '/a/b/d' as SQL NVARCHAR(200) SINGLETON
);
형식화된 XML에 대한 선택적 XML 인덱스 지원 이해
SQL Server의 형식화된 XML은 지정된 XML 문서와 연결된 스키마입니다. 스키마는 전체적인 문서 구조 및 노드 유형을 정의합니다. 스키마가 있으면 사용자가 경로를 승격시킬 때 선택적 XML 인덱스가 해당 스키마 구조를 적용하기 때문에 경로에 대한 XQUERY 유형을 지정할 필요가 없습니다.
선택적 XML 인덱스는 다음의 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
연결된 스키마가 있는 문서에 대해 선택적 XML 인덱스를 생성할 때 인덱스를 만들거나 변경할 때 XQuery 형식을 지정하면 오류가 반환됩니다. 사용자는 경로 승격 부분에서 SQL 형식 주석을 사용할 수 있습니다. SQL 형식은 스키마에 정의된 XSD 형식에서 유효한 변환이어야 하며, 그렇지 않으면 오류가 반환됩니다. 날짜/시간 형식을 제외한 XSD에서 적절한 표현이 있는 모든 SQL 형식이 지원됩니다.
참고 항목
선택적 XML 인덱스 경로 승격에 지정된 형식이 value()
메서드 반환 값과 동일한 경우 선택적 인덱스가 사용됩니다.
다음은 형식화된 XML 문서에서 사용할 수 있는 최적화 힌트입니다.
node()
최적화 힌트.MAXLENGTH 최적화 힌트를 xs:string 형식과 함께 사용하여 인덱싱된 값을 줄일 수 있습니다.
최적화 힌트에 대한 자세한 내용은 최적화 힌트 지정을 참조하세요.
경로 지정
선택적 XML 인덱스를 사용하면 저장된 XML 데이터에서 실행할 쿼리와 관련 있는 노드의 하위 집합만 인덱싱할 수 있습니다. 관련 노드의 하위 집합이 XML 문서의 총 노드 수보다 훨씬 작은 경우 선택적 XML 인덱스는 관련 노드만 저장합니다. 선택적 XML 인덱스를 사용하려면 인덱싱할 노드의 올바른 하위 집합을 식별해야 합니다.
인덱싱할 노드 선택
다음 두 가지 원칙을 사용하여 선택적 XML 인덱스에 추가할 노드의 올바른 하위 집합을 식별할 수 있습니다.
원칙 1: 지정된 XQuery 식을 평가하기 위해 검사해야 하는 모든 노드를 인덱싱합니다.
XQuery 식에서 존재 또는 값이 사용되는 모든 노드를 인덱싱합니다.
XQuery 조건자가 적용되는 XQuery 식의 모든 노드를 인덱싱합니다.
이 문서의 샘플 XML 문서에 대해 다음의 쿼리를 고려합니다.
SELECT T.record FROM myXMLTable T WHERE T.xmldata.exist('/a/b[./c = "43"]') = 1;
이 쿼리를 충족하는 XML 인스턴스를 반환하려면 선택적 XML 인덱스는 모든 XML 인스턴스에서 두 개의 노드를 검사해야 합니다.
노드
c
, 해당 값이 XQuery 식에 사용되기 때문입니다.노드
b
, XQuery 식의 노드b
에 대해 조건자가 적용되기 때문입니다.
원칙 2: 최상의 성능을 위해 지정된 XQuery 식 평가에 필요한 모든 노드를 인덱싱합니다. 일부 노드만 인덱싱하는 경우 선택적 XML 인덱스는 인덱싱된 노드만 포함하는 하위 식에 대한 평가를 향상시킵니다.
위에 표시된 SELECT 문의 성능을 향상시키기 위해 다음의 선택적 XML 인덱스를 생성할 수 있습니다.
CREATE SELECTIVE XML INDEX simple_sxi
ON Tbl(xmlcol)
FOR
(
path123 = '/a/b',
path124 = '/a/b/c'
);
동일한 경로 인덱싱
동일한 경로를 다른 경로 이름 아래에 있는 동일한 데이터 형식으로 승격할 수 없습니다. 예를 들어 다음 쿼리는 pathOne
과 pathTwo
이 동일하기 때문에 오류를 발생합니다.
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'
);
그러나 동일한 경로를 다른 이름을 갖는 다른 데이터 형식으로 승격할 수 있습니다. 예를 들어 다음 쿼리는 데이터 형식이 다르기 때문에 허용될 수 있습니다.
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'
);
예제
다음은 다른 XQuery 형식에 대한 인덱싱을 위한 올바른 노드를 선택하는 몇 가지 예입니다.
예제 1
다음은 exist()
메서드를 사용하는 간단한 XQuery입니다.
SELECT T.record FROM myXMLTable T
WHERE T.xmldata.exist('/a/b/c/d/e/h') = 1;
다음 표에서는 이 쿼리가 선택적 XML 인덱스를 사용할 수 있도록 하기 위해 인덱싱해야 하는 노드를 보여 줍니다.
인덱스에 포함할 노드 | 이 노드를 인덱싱하는 이유 |
---|---|
/a/b/c/d/e/h | 노드 h 의 존재 여부가 exist() 메서드에 의해 평가됩니다. |
예제 2
다음은 조건자가 적용된 이전 XQuery의 보다 복잡한 변형입니다.
SELECT T.record FROM myXMLTable T
WHERE T.xmldata.exist('/a/b/c/d/e[./f = "SQL"]') = 1;
다음 표에서는 이 쿼리가 선택적 XML 인덱스를 사용할 수 있도록 하기 위해 인덱싱해야 하는 노드를 보여 줍니다.
인덱스에 포함할 노드 | 이 노드를 인덱싱하는 이유 |
---|---|
/a/b/c/d/e | 조건자가 e 노드를 통해 적용됩니다. |
/a/b/c/d/e/f | 노드 f 의 값은 조건자 내에서 평가됩니다. |
예제 3
value()
절이 포함된 더 복잡한 쿼리는 다음과 같습니다.
SELECT T.record,
T.xmldata.value('(/a/b/c/d/e[./f = "SQL"]/g)[1]', 'nvarchar(100)')
FROM myXMLTable T;
다음 표에서는 이 쿼리가 선택적 XML 인덱스를 사용할 수 있도록 하기 위해 인덱싱해야 하는 노드를 보여 줍니다.
인덱스에 포함할 노드 | 이 노드를 인덱싱하는 이유 |
---|---|
/a/b/c/d/e | 조건자가 e 노드를 통해 적용됩니다. |
/a/b/c/d/e/f | 노드 f 의 값은 조건자 내에서 평가됩니다. |
/a/b/c/d/e/g | g 노드의 값이 value() 메서드에 의해 반환됩니다. |
예제 4
다음은exist()
절 내의 FLWOR 절을 사용하는 쿼리입니다. (FLWOR 명칭은 XQuery FLWOR 식을 구성할 수 있는 다섯 가지 절인 for, let, where, order by 및 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;
다음 표에서는 이 쿼리가 선택적 XML 인덱스를 사용할 수 있도록 하기 위해 인덱싱해야 하는 노드를 보여 줍니다.
인덱스에 포함할 노드 | 이 노드를 인덱싱하는 이유 |
---|---|
/a/b/c/d/e | 노드 e 의 존재는 FLWOR 절에서 평가됩니다. |
/a/b/c/d/e/f | 노드 f 값은 FLWOR 절에서 평가됩니다. |
/a/b/c/d/e/g | 노드 g 의 존재 여부는 exist() 메서드에 의해 평가됩니다. |
최적화 힌트 지정
선택적 최적화 힌트를 사용하여 선택적 XML 인덱스에 의해 인덱싱된 노드의 추가 매핑 세부 정보를 지정할 수 있습니다. 예를 들어 노드의 데이터 형식 및 카디널리티과 데이터 구조에 대한 특정 정보를 지정할 수 있습니다. 이 추가 정보는 더 나은 매핑을 지원합니다. 또한, 성능이나 스토리지 또는 두 가지 모두에 대한 향상을 달성합니다.
최적화 힌트의 사용은 선택 사항입니다. 항상 기본 매핑을 수락할 수 있으며, 이는 신뢰할 수 있지만 최적의 성능 및 스토리지를 제공하지 않을 수 있습니다.
SINGLETON 힌트와 같은 일부 최적화 힌트는 데이터에 대한 제약 조건을 도입합니다. 일부 경우에는 이러한 제약 조건이 충족되지 않을 때 오류가 발생할 수 있습니다.
최적화 힌트의 이점
다음 표에서는 보다 효율적인 스토리지 및 향상된 성능을 지원하는 최적화 힌트를 보여 줍니다.
최적화 힌트 | 보다 효율적인 스토리지 | 성능 향상 |
---|---|---|
node() | 예 | 아니요 |
SINGLETON | 예 | 예 |
데이터 형식 | 예 | 예 |
MAXLENGTH | 예 | 예 |
최적화 힌트 및 데이터 형식
노드를 XQuery 데이터 형식 또는 SQL Server 데이터 형식으로 인덱싱할 수 있습니다. 다음의 표는 각 데이터 형식에서 지원되는 최적화 힌트를 보여 줍니다.
최적화 힌트 | XQuery 데이터 형식 | SQL 데이터 형식 |
---|---|---|
node() | 예 | 아니요 |
SINGLETON | 예 | 예 |
데이터 형식 | 예 | 아니요 |
MAXLENGTH | 예 | 아니요 |
node() 최적화 힌트
적용 대상: XQuery 데이터 형식
node()
최적화를 사용하여 일반적인 쿼리를 평가하는 데 값이 필요하지 않은 노드를 지정할 수 있습니다. 이 힌트는 일반적인 쿼리가 노드의 존재만 평가해야 할 때 스토리지 요구 사항을 줄입니다. (기본 설정으로 선택적 XML 인덱스는 복합 노드 형식을 제외한 모든 승격된 노드의 값을 저장합니다.)
다음 예시를 참조하세요.
SELECT T.record FROM myXMLTable T
WHERE T.xmldata.exist('/a/b[./c=5]') = 1;
선택적 XML 인덱스를 사용하여 이 쿼리를 평가하려면 b
및 c
노드를 승격시킵니다. 그러나 노드 b
의 값은 필요하지 않으므로 다음 구문과 함께 node()
힌트를 사용할 수 있습니다.
`/a/b/ as node()
쿼리에 node()
힌트를 사용하여 인덱싱된 노드의 값이 필요한 경우 선택적 XML 인덱스를 사용할 수 없습니다.
SINGLETON 최적화 힌트
적용 대상: XQuery 또는 SQL Server 데이터 형식
SINGLETON 최적화 힌트는 노드의 카디널리티를 지정합니다. 이 힌트를 사용하면 노드가 해당 부모 노드 또는 상위 항목에 최대 한 번만 표시된다는 것을 미리 알 수 있기 때문에 쿼리 성능이 향상됩니다.
이 문서의 샘플 XML 문서를 고려합니다.
선택적 XML 인덱스를 사용하여 이 문서를 쿼리하기 위해 해당 부모 내에 최대 한 번 표시되기 때문에 노드 d
에 대한 SINGLETON 힌트를 지정할 수 있습니다.
SINGLETON 힌트가 지정되었지만 노드가 해당 부모 노드 또는 상위 항목에 두 번 이상 표시되면 기존 데이터에 대한 인덱스를 만들거나 새 데이터에 대한 쿼리를 실행할 때 오류가 발생합니다.
DATA TYPE 최적화 힌트
적용 대상: XQuery 데이터 형식
DATA TYPE 최적화 힌트를 사용하면 인덱싱된 노드에 대해 XQuery 또는 SQL Server 데이터 형식을 지정할 수 있습니다. 데이터 형식은 인덱싱된 노드에 해당하는 선택적 XML 인덱스의 데이터 테이블에 있는 열에 사용됩니다.
기존의 값을 지정된 데이터 형식으로 캐스팅하지 못하면, 삽입 작업(인덱스로)은 실패하지 않습니다. 하지만, null 값은 인덱스의 데이터 테이블에 삽입됩니다.
MAXLENGTH 최적화 힌트
적용 대상: XQuery 데이터 형식
MAXLENGTH 최적화 힌트를 사용하면 xs:string 데이터의 길이를 제한할 수 있습니다. VARCHAR 또는 NVARCHAR 날짜 형식을 지정할 때 길이를 지정하기 때문에 MAXLENGTH는 SQL Server 데이터 형식과는 관련이 없습니다.
기존의 문자열이 지정된 MAXLENGTH보다 길면 해당 값을 인덱스로 삽입하지 못합니다.
예제에 대한 샘플 XML 문서
다음의 샘플 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>