다음을 통해 공유


CREATE JSON INDEX(Transact-SQL)

적용 대상: SQL Server 2025(17.x) 미리 보기

SQL Server 2025(17.x) 미리 보기에서 지정된 테이블 및 열에 JSON 인덱스 만들기

JSON 인덱스:

  • 테이블에 데이터가 있기 전에 만들 수 있습니다.
  • 정규화된 데이터베이스 이름을 지정하여 다른 데이터베이스의 테이블에 만들 수 있습니다.
  • 테이블에 클러스터형 기본 키가 있어야 합니다.
  • 인덱싱된 뷰에서는 지정할 수 없습니다.

비고

JSON 인덱스 만들기는 현재 미리 보기 상태이며 SQL Server 2025(17.x) 미리 보기에서만 사용할 수 있습니다.

Transact-SQL 구문 표기 규칙

문법

CREATE JSON INDEX name ON table_name (json_column_name)
  [ FOR ( sql_json_path [ , ...n ] ) ]
  [ WITH ( <json_index_option> [ , ...n ] ) ]
  [ ON { filegroup_name | "default" } ]
[ ; ]

<object> ::=
    { database_name.schema_name.table_name | schema_name.table_name | table_name }

<sql_json_path> ::=
    { character_string_literal }

<json_index_option> ::=
{
    FILLFACTOR = fillfactor
  | DROP_EXISTING = { ON | OFF }
  | ONLINE = OFF
  | ALLOW_ROW_LOCKS = { ON | OFF }
  | ALLOW_PAGE_LOCKS = { ON | OFF }
  | MAXDOP = max_degree_of_parallelism
  | DATA_COMPRESSION = { NONE | ROW | PAGE }
}

주장들

인덱스_이름

인덱스의 이름입니다. 인덱스 이름은 테이블 내에서 고유해야 하지만 데이터베이스 내에서 고유할 필요는 없습니다. 인덱 스 이름은 식별자 규칙을 따라야 합니다.

  • ON <개체> ( json_column_name )

    인덱스를 만들 개체(데이터베이스, 스키마 또는 테이블)와 json 열의 이름을 지정합니다.

  • json_column_name

    지정된 SQL/JSON 경로가 0개 이상 포함된 json 데이터 형식 table_name 의 열 이름입니다.

  • sql_json_path

    json_column_name에서 추출하여 인덱싱해야 하는 SQL/JSON 경로입니다. sql_json_path에 대한 기본값은 $입니다.

    • 지정된 경로부터 모든 키/값을 재귀적으로 인덱싱합니다.
    • JSON 문서 경로에서 최대 128개의 수준을 지원합니다.
    • 겹치는 것을 허용하지 않습니다.

    예를 들어, $.a$.a.b는 오류를 발생시킵니다. 이는 $.a가 모든 경로를 재귀적으로 포함하고 있어 사용자 의도가 불분명하기 때문입니다.

ON filegroup_name

주어진 파일 그룹에 지정된 인덱스를 만듭니다. 위치를 지정하지 않고 테이블이 분할되지 않은 경우 인덱스는 기본 테이블과 동일한 파일 그룹을 사용합니다. 파일 그룹이 이미 있어야 합니다.

ON "기본값"

기본 파일 그룹에 지정된 인덱스 만듭니다.

이 컨텍스트에서 기본 용어는 키워드가 아닙니다. 기본 파일 그룹에 대한 식별자이며, 와 ON "default"ON [default]같이 구분되어야 합니다. 지정한 "default" 경우 QUOTED_IDENTIFIER 현재 세션에 대한 옵션이어야 ON 합니다. 기본 설정입니다. 자세한 내용은 SET QUOTED_IDENTIFIER 참조하세요.

<object>:: =

인덱싱할 정규화된 개체 또는 정규화되지 않은 개체입니다.

  • database_name

    데이터베이스의 이름입니다.

  • schema_name

    테이블이 속한 스키마의 이름입니다.

  • table_name

    인덱싱할 테이블의 이름입니다.

FILLFACTOR = fillfactor

인덱스를 만들거나 다시 작성할 때 데이터베이스 엔진에서 각 인덱스 페이지의 리프 수준을 채우는 비율을 지정합니다. fillfactor 는 다음의 정수 값 1100이어야 합니다. 기본값은 0입니다. fillfactor가 있는 경우 데이터베이스 100엔진은 0 리프 페이지가 용량으로 채워진 인덱스를 만듭니다.

비고

채우기 비율 값 0100 모든 면에서 동일합니다.

FILLFACTOR 설정은 인덱스를 만들거나 다시 빌드할 때만 적용됩니다. 데이터베이스 엔진에서는 페이지에 지정된 비율의 빈 공간을 동적으로 유지하지 않습니다. 채우기 비율 설정을 보려면 sys.indexes 카탈로그 뷰를 사용합니다.

FILLFACTOR이(가) 100보다 작은 클러스터형 인덱스를 만들면 데이터베이스 엔진이 클러스터형 인덱스를 만들 때 데이터를 재배포하기 때문에 데이터가 차지하는 스토리지 공간의 양에 영향을 줍니다.

자세한 내용은 인덱스의 채우기 비율 지정을 참조하세요.

DROP_EXISTING = { 켜짐 | 꺼짐 }

명명된 기존 공간 인덱스를 삭제하고 다시 작성되도록 지정합니다. 기본값은 OFF입니다.

  • 켜짐

    기존 인덱스가 삭제되고 다시 작성됩니다. 지정된 인덱스 이름은 현재 기존 인덱스여야 합니다. 그러나 인덱스 정의를 수정할 수 있습니다. 예를 들어 다른 열, 정렬 순서, 파티션 구성표 또는 인덱스 옵션을 지정할 수 있습니다.

  • OFF

    지정한 인덱스 이름이 이미 있으면 오류가 표시됩니다.

인덱스 형식은 .를 사용하여 DROP_EXISTING변경할 수 없습니다.

ONLINE = OFF

인덱스 작업 중에 쿼리 및 데이터 수정에 기본 테이블 및 관련 인덱스를 사용할 수 없게 지정합니다. 이 버전의 SQL Server에서는 JSON 인덱스에 대해 온라인 인덱스 빌드가 지원되지 않습니다. JSON 인덱스로 ON 이 옵션을 설정하면 오류가 발생합니다. 옵션을 생략하거나 .ONLINEONLINE설정합니다OFF.

JSON 인덱스를 만들거나, 다시 작성하거나, 삭제하고, 테이블에 대한 스키마 수정(Sch-M) 잠금을 획득하는 오프라인 인덱스 작업입니다. 이 경우 작업 중에 모든 사용자가 기본 테이블에 액세스할 수 없게 됩니다.

온라인 인덱스 작업은 모든 SQL Server 버전에서 사용 가능한 것은 아닙니다.

Windows의 SQL Server 버전에서 지원되는 기능 목록은 다음을 참조하세요.

ALLOW_ROW_LOCKS = { 켜기 | 끄기 }

행 잠금이 허용되는지 여부를 지정합니다. 기본값은 ON입니다.

  • 켜짐

    인덱스에 액세스할 때 행 잠금이 허용됩니다. 행 잠금을 사용하는 시점은 데이터베이스 엔진이 결정합니다.

  • OFF

    행 잠금은 사용되지 않습니다.

ALLOW_PAGE_LOCKS = { ON | OFF }

페이지 잠금이 허용되는지 여부를 지정합니다. 기본값은 ON입니다.

  • 켜짐

    인덱스에 액세스할 때 페이지 잠금이 허용됩니다. 페이지 잠금을 사용하는 시점은 데이터베이스 엔진이 결정합니다.

  • OFF

    페이지 잠금은 사용되지 않습니다.

MAXDOP = max_degree_of_parallelism

인덱스 max degree of parallelism 작업 기간 동안 구성 옵션을 덮어씁니다. 병렬 계획 실행에 사용되는 프로세서 수를 제한하는 데 사용합니다 MAXDOP . 최대 프로세서는 64개입니다.

중요합니다

MAXDOP 이 옵션은 구문적으로 지원 CREATE SPATIAL INDEX 되지만 현재는 항상 단일 프로세서만 사용합니다.

max_degree_of_parallelism 다음 값 중 하나일 수 있습니다.

가치 설명
1 병렬 계획 생성을 억제합니다.
>1 병렬 인덱스 작업에 사용되는 최대 프로세서 수를 현재 시스템 작업에 따라 지정된 수 또는 더 적은 수로 제한합니다.
0(기본값) 현재 시스템 작업에 따라 실제 프로세서 수 이하의 프로세서를 사용합니다.

자세한 내용은 병렬 인덱스 작업 구성을 참조하세요.

병렬 인덱스 작업은 일부 SQL Server 버전에서 사용할 수 있습니다.

Windows의 SQL Server 버전에서 지원되는 기능 목록은 다음을 참조하세요.

DATA_COMPRESSION = { 없음 (NONE) | 행 (ROW) | 페이지 (PAGE) }

인덱스에 사용되는 데이터 압축 수준을 결정합니다.

  • 없음

    인덱스가 데이터에 압축을 사용하지 않음

  • 인덱스가 데이터에 사용하는 행 압축

  • 페이지

    인덱스가 사용하는 데이터의 페이지 압축

비고

모든 옵션은 문당 CREATE JSON INDEX 한 번만 지정할 수 있습니다. 모든 옵션의 중복을 지정하면 오류가 발생합니다.

[ ON { filegroup_name | "default" } ]

JSON 인덱스에 대한 파일 그룹을 지정하면 테이블의 분할 체계에 관계없이 인덱스가 해당 파일 그룹에 배치됩니다.

인덱스를 만드는 방법에 대한 자세한 내용은 CREATE INDEX의 설명 섹션을 참조하세요.

JSON 인덱스로 지원되는 조건자

JSON 열에 JSON 인덱스가 있는 경우 테이블의 json열에 포함된 JSON 문서에 대한 검색 작업을 최적화할 수 있습니다. JSON 인덱스는 다양한 JSON 함수 기반 식이 있는 쿼리에서 사용됩니다.

다음 예제에서는 Sales.SalesOrderHeader 열이 호출AdventureWorks2022된 데이터베이스의 테이블을 사용합니다Info. 열이 Infojson 형식으로 만들어집니다. Info 열에 기본 설정으로 JSON 인덱스가 또한 생성됩니다. 다음 코드 샘플에서는 CREATE JSON INDEX 문을 보여줍니다.

CREATE JSON INDEX sales_info_idx ON Sales.SalesOrderHeader(Info);

샘플 검색 식의 경우 다음 JSON 문서를 데이터로 사용합니다.

판매 주문 번호 정보
437 {"Customer":{"Name":"Kelsey Raje","ID":16517,"Type":"IN"},"Order":{"ID":43710,"Number":"SO43710","CreationDate":"2011-06-02T00:00:00","TotalDue":3953.9884}}
643 {"Customer":{"Name":"Aaron Campbell","ID":16167,"Type":"IN"},"Order":{"ID":64304,"Number":"SO64304","CreationDate":"2014-01-16T00:00:00","TotalDue":36.0230, "IsProcessed": true}}

JSON_PATH_EXISTS 함수

JSON_PATH_EXISTS 함수를 사용하여 지정된 SQL/JSON 경로가 JSON 문서에 있는지 테스트합니다.

이 쿼리는 JSON 인덱스를 JSON_PATH_EXISTS 사용하여 최적화할 수 있는 json 열에 대해 설명합니다.

SELECT COUNT(*)
FROM Sales.SalesOrderHeader
WHERE JSON_PATH_EXISTS(Info, '$.Order.IsProcessed') = 1;

JSON 인덱스는 JSON_PATH_EXISTS 조건자 및 다음 연산자와 함께 지원됩니다.

  • 비교 연산자(=)
  • IS [NOT] NULL 조건자(현재 지원되지 않음)

JSON_VALUE 함수

JSON_VALUE 사용하여 JSON 문서의 지정된 SQL/JSON 경로에서 JSON 텍스트/스칼라 값을 추출합니다. JSON_VALUE 열에서 표현식을 JSON 인덱스를 사용하여 최적화하는 방법을 보여주는 쿼리는 다음과 같습니다.

  • 객체의 속성에서 JSON 문자열을 동일성 검색하기.

    SELECT COUNT(*)
    FROM Sales.SalesOrderHeader
    WHERE JSON_VALUE(Info, '$.Customer.Type') = 'IN';
    
  • 값을 int 데이터 형식으로 변환한 후 JSON 번호와 개체 속성의 일치를 검색합니다.

    SELECT *
    FROM Sales.SalesOrderHeader
    WHERE JSON_VALUE(Info, '$.Customer.ID' RETURNING INT) = 16167;
    
  • 값을 int 데이터 형식으로 변환한 후 개체 속성에서 JSON 번호를 검색하는 범위:

    SELECT *
    FROM Sales.SalesOrderHeader
    WHERE JSON_VALUE(Info, '$.Customer.ID' RETURNING INT) IN (16167, 16517);
    
  • 값을 10진 수 데이터 형식으로 변환한 후 개체 속성에서 JSON 번호를 검색하는 범위:

    SELECT *
    FROM Sales.SalesOrderHeader
    WHERE JSON_VALUE(Info, '$.Order.TotalDue RETURNING decimal(20, 4)) BETWEEN 1000 and 2000;
    

JSON 인덱스는 JSON_VALUE 조건자와 다음 연산자를 통해 지원됩니다.

  • 비교 연산자(=)
  • LIKE 서술어(현재 지원되지 않음)
  • IS [NOT] NULL 서술어(현재 지원되지 않음)

JSON_CONTAINS 함수

JSON_CONTAINS 함수는 JSON 열에 있는 경우 JSON 인덱스를 사용할 수 있는 JSON 문서에서 JSON 값을 쉽게 검색할 수 있도록 지원합니다. 이 함수를 사용하여 JSON 문서의 지정된 SQL/JSON 경로에 JSON 스칼라 값, 개체 또는 배열이 포함되어 있는지 테스트할 수 있습니다. SQL 스칼라 형식으로 지정된 검색 값은 기존 SQL/JSON 형식 변환에 따라 변환됩니다. 이러한 규칙은 동작 섹션에서 정의됩니다.

요구 사항

클러스터링 키는 JSON 열이 포함된 테이블에 필요합니다. 클러스터링 키가 없는 경우 오류가 발생합니다. 클러스터링 키는 31열로 제한되며 인덱스 키의 최대 크기는 128바이트 미만이어야 합니다.

권한

사용자는 ALTER 테이블에 대한 권한이 있거나, sysadmin 고정 서버 역할의 멤버이거나, 고정 데이터베이스 역할의 db_ddladmindb_owner의 멤버여야 합니다.

제한점

JSON 인덱스 문에는 다음과 같은 제한 사항이 있습니다.

  • 테이블의 json 열에 하나의 JSON 인덱스만 만들 수 있습니다.
  • 테이블에서 최대 249개의 JSON 인덱스를 만들 수 있습니다. 특정 JSON 열에 둘 이상의 JSON 인덱스 만들기는 지원되지 않습니다.
  • 계산된 json 열에는 JSON 인덱스를 만들 수 없습니다.
  • 뷰, 테이블 반환 변수 또는 메모리 최적화 테이블의 json 열에는 JSON 인덱스를 만들 수 없습니다.
  • JSON 인덱스 만들기 또는 오프라인 방식으로만 변경할 수 있습니다.
  • JSON 경로는 인덱스 정의에서 겹칠 수 없습니다. 예를 들어 $a$a.b가 겹치며, CREATE JSON INDEX 문장에서는 허용되지 않습니다.
  • 경로를 수정하려면 JSON 인덱스를 다시 만들어야 합니다.
  • JSON 인덱스는 인덱스 힌트에서 지원되지 않습니다.
  • 데이터 압축 옵션은 지원되지 않습니다.

예시

A. JSON 열에 JSON 인덱스 만들기

다음 예제에서는 docs 형식 열이 포함된 테이블을 content 만듭니다. 그런 다음, json_content_index 열에 JSON 인덱스 content가 생성됩니다. 이 예제에서는 전체 JSON 문서 또는 JSON 문서의 모든 SQL/JSON 경로에 json 인덱스를 만듭니다.

DROP TABLE IF EXISTS docs;

CREATE TABLE docs (content JSON, id INT PRIMARY KEY);
CREATE JSON INDEX json_content_index ON docs(content);

A. 특정 경로를 사용하여 JSON 열에 JSON 인덱스 만들기

다음 예제에서는 docs 형식 열이 포함된 테이블을 content 만듭니다. 그런 다음, json_content_index 열에 JSON 인덱스 content가 생성됩니다. 이 예제에서는 JSON 문서의 특정 SQL/JSON 경로에 json 인덱스를 만듭니다.
또한 이 예제에서는 인덱스 FILLFACTOR를 80.로 설정합니다.

DROP TABLE IF EXISTS docs;

CREATE TABLE docs (content JSON, id INT PRIMARY KEY);

CREATE JSON INDEX json_content_index
    ON docs(content) FOR ('$.a', '$.b')
    WITH (FILLFACTOR = 80);