SQL Server 의 초점 필터 인덱스 를 자세히 설명 합 니 다.
10689 단어 sqlserver포커 싱 필터 인덱스
이 절 에서 우 리 는 색인 지식 을 계속 이야기 합 니 다.앞에서 우 리 는 색인,비 집합 색인 과 커버 색인 등 을 모 았 습 니 다.그 중에서 여과 색인 도 있 습 니 다.색인 을 통 해 우 리 는 조회 성능,짧 은 내용 을 향상 시 키 고 깊이 이해 할 수 있 습 니 다.
색인 필터,검색 조건 에서 비 집합 색인 만 들 기(1)
필터 색인 은 SQL 2008 의 새로운 기능 으로 표 의 일부 줄 에 적용 되 기 때문에 필터 색인 을 이용 하여 검색 을 높 일 수 있 습 니 다.전체 표 스 캔 에 비해 색인 유지 와 색인 저장 의 대 가 를 줄 일 수 있 습 니 다.색인 에 WHERE 조건 을 적용 할 때 색인 을 필터 합 니 다.즉,다음 과 같은 형식 을 만족 시 키 는 것 이다.
CREATE NONCLUSTERED INDEX <index name>
ON <table> (<columns>)
WHERE <criteria>;
GO
다음은 간단 한 조 회 를 보 겠 습 니 다.
USE AdventureWorks2012
GO
SELECT SalesOrderDetailID, UnitPrice
FROM Sales.SalesOrderDetail
WHERE UnitPrice > 2000
GO
상기 열 에 어떠한 색인 도 만 들 지 않 았 습 니 다.물론 SalesOrder DetailID 가 기본적으로 만 든 집합 색인 을 제외 하고 실 행 된 조회 계획 은 반드시 홈 키 가 만 든 집합 색인 스 캔 이 라 고 추측 할 수 있 습 니 다.다음 과 같 습 니 다.위 에서 말 했 듯 이 이 때 는 검색 조건 에 색인 을 만 들 지 않 았 기 때문에 이 때 는 반드시 홈 키 가 만 든 집합 색인 을 가 야 합 니 다.그 다음 에 우 리 는 먼저 UnitPrice 열 에 비 집합 색인 을 만들어 검색 성능 을 향상 시 킵 니 다.
CREATE NONCLUSTERED INDEX idx_SalesOrderDetail_UnitPrice
ON Sales.SalesOrderDetail(UnitPrice)
이때 우 리 는 다시 두 사람 이 지출 을 조회 하 는 것 을 비교 해 보 자.
USE AdventureWorks2012
GO
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
SELECT SalesOrderDetailID, UnitPrice
FROM AdventureWorks2012.Sales.SalesOrderDetail WITH(INDEX([PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID]))
WHERE UnitPrice > 2000
GO
SELECT SalesOrderDetailID, UnitPrice
FROM Sales.SalesOrderDetail WITH(INDEX([idx_SalesOrderDetail_UnitPrice]))
WHERE UnitPrice > 2000
이때 검색 조건 에 비 집합 색인 을 만 든 후 검색 비용 이 90%이상 올 랐 습 니 다.비 집합 색인 도 홈 키 가 만 든 집합 색인 을 참조 하기 때문에 이 럴 때 북 마크 룩 업 이나 키 룩 업 이 찾 지 않 습 니 다.다음 에 우 리 는 조건 이 있 는 비 집합 색인 즉 필터 색인 을 추가 합 니 다.
CREATE NONCLUSTERED INDEX idxwhere_SalesOrderDetail_UnitPrice
ON Sales.SalesOrderDetail(UnitPrice)
WHERE UnitPrice > 1000
이때 필터 색인 을 만 든 후 이전 비 집합 색인 성능 과 비용 차 이 를 살 펴 보 겠 습 니 다.
USE AdventureWorks2012
GO
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
SELECT SalesOrderDetailID, UnitPrice
FROM AdventureWorks2012.Sales.SalesOrderDetail WITH(INDEX([idx_SalesOrderDetail_UnitPrice]))
WHERE UnitPrice > 2000
SELECT SalesOrderDetailID, UnitPrice
FROM Sales.SalesOrderDetail WITH(INDEX([idxwhere_SalesOrderDetail_UnitPrice]))
WHERE UnitPrice > 2000
이때 우 리 는 만 든 비 집합 필터 색인 이 전통 적 으로 만 든 비 집합 색인 에 비해 우리 의 조 회 는 절반 가까이 줄 어 들 었 다 는 것 을 알 고 있다.
유일한 필터 인덱스
유일한 필터 색인 은 모든 열 에 유일 하고 비어 있 지 않 아야 합 니 다.(하나의 NULL 만 존재 할 수 있 습 니 다)또한 좋 은 해결 방안 입 니 다.따라서 유일한 필터 색인 을 만 들 때 NULL 값 을 제외 해 야 합 니 다.예 를 들 어 다음 과 같 습 니 다.
CREATE UNIQUE NONCLUSTERED INDEX uq_fix_Customers_Email
ON Customers(Email)
WHERE Email IS NOT NULL
GO
필터 인덱스 결합 INCLUDE추가 열 을 추가 할 때 기본 키 로 만 든 집합 색인 을 사용 할 때 집합 색인 검색 을 한 다음 검색 조건 에서 필터 색인 을 만 듭 니 다.이 필터 색인 을 강제로 사용 할 때 추가 열 을 추가 하기 때문에 기본 표 로 돌아 가서 데 이 터 를 가 져 와 야 하기 때문에 Key Lookup 에서 찾 습 니 다.다음 과 같 습 니 다.
USE AdventureWorks2012
GO
SELECT SalesOrderDetailID, UnitPrice, UnitPriceDiscount
FROM Sales.SalesOrderDetail
WHERE UnitPrice > 2000
GO
이때 우 리 는 INCLUDE 로 추가 열 을 포함 해 야 한다.
CREATE NONCLUSTERED INDEX [idx_SalesOrderDetail_UnitPrice] ON Sales.SalesOrderDetail(UnitPrice) INCLUDE(UnitPriceDiscount)
필터 색인 을 만 들 고 추가 열 을 포함 합 니 다.
CREATE NONCLUSTERED INDEX [idxwhere_SalesOrderDetail_UnitPrice] ON Sales.SalesOrderDetail(UnitPrice) INCLUDE(UnitPriceDiscount)
WHERE UnitPrice > 2000
다음은 필터 색인 을 추가 하 는 것 과 필터 색인 을 추가 하지 않 는 것 을 비교 하 는 동시에 추가 열의 성능 조회 차 이 를 포함한다.
SELECT SalesOrderDetailID, UnitPrice, UnitPriceDiscount
FROM AdventureWorks2012.Sales.SalesOrderDetail WITH(INDEX([idx_SalesOrderDetail_UnitPrice]))
WHERE UnitPrice > 2000
SELECT SalesOrderDetailID, UnitPrice, UnitPriceDiscount
FROM Sales.SalesOrderDetail WITH(INDEX([idxwhere_SalesOrderDetail_UnitPrice]))
WHERE UnitPrice > 2000
이때 추가 열 을 INCLUDE 로 포함 하 는 성능 도 어느 정도 개선 됐다.
색인 필터,홈 키 에 비 집합 색인 만 들 기(2)
첫 번 째 사례 열 에서 우 리 는 검색 열 에 비 집합 색인 을 직접 만 들 수 있 습 니 다.그 유형 은 디지털 형식 이기 때문에 검색 조건 이 문자 형식 이 라면?첫 번 째 선택 은 지금 테스트 표를 만 듭 니 다.
USE TSQL2012
GO
CREATE TABLE dbo.TestData
(
RowID integer IDENTITY NOT NULL,
SomeValue VARCHAR(max) NOT NULL,
StartDate date NOT NULL,
CONSTRAINT PK_Data_RowID
PRIMARY KEY CLUSTERED (RowID)
);
테스트 데이터 10 만 개 추가
USE TSQL2012
GO
INSERT dbo.TestData WITH (TABLOCKX)
(SomeValue, StartDate)
SELECT
CAST(N.n AS VARCHAR(max)) + 'JeffckyWang',
DATEADD(DAY, (N.n - 1) % 31, '20140101')
FROM dbo.Nums AS N
WHERE
N.n >= 1
AND N.n < 100001;
표 TestData 에서 SomeValue='JeffckyWang'을 가 져 올 필요 가 있다 면,SomeValue 에 비 집합 색인 을 만 들 고 필 터 를 하려 면 다음 과 같 습 니 다.
USE TSQL2012
GO
CREATE NONCLUSTERED INDEX idx_noncls_somevalue
ON dbo.TestData(SomeValue)
WHERE SomeValue = 'JeffckyWang'
업데이트
SQL Server 는 생 성 색인 크기 에 제한 이 있 으 며 최대 900 바이트 이 며 위 에 직접 쓴 VARCHAR(MAX)이기 때문에 오류 가 발생 할 수 있 습 니 다.
이 때 우 리 는 홈 키 에 비 집합 색인 을 만 듭 니 다.홈 키 RowID 에 필터 색인 을 만 들 고 SomeValue='Jeffcky Wang'을 만 든 다음 데 이 터 를 되 돌려 줍 니 다.다음 과 같 습 니 다.
CREATE NONCLUSTERED INDEX idxwhere_noncls_somevalue
ON dbo.TestData(RowID)
WHERE SomeValue = 'JeffckyWang'
필터 색인 생 성 전후 조회 계획 결 과 를 비교 해 보 겠 습 니 다.
USE TSQL2012
GO
SELECT RowID, SomeValue, StartDate
FROM dbo.TestData WITH(INDEX([idx_pk_rowid]))
WHERE SomeValue = 'JeffckyWang'
SELECT RowID, SomeValue, StartDate
FROM dbo.TestData WITH(INDEX([idxwhere_noncls_somevalue]))
WHERE SomeValue = 'JeffckyWang'
그리고 이전에 배 운 것 과 결합 하여 Key Lookup 을 제거 하고 만 든 필터 색인 을 INCLUDE 합 니 다.
CREATE NONCLUSTERED INDEX [idxwhere_noncls_somevalue] ON dbo.TestData(RowID) INCLUDE(SomeValue,StartDate)
WHERE SomeValue = 'JeffckyWang'
이 를 통 해 알 수 있 듯 이 조회 조건 에 대한 필터 색인 을 만 들 든 메 인 키 에 대한 필터 색인 을 만 들 든 우 리 는 이전에 배 운 것 과 결합 하여 조회 성능 을 향상 시 킬 수 있다.
우 리 는 처음부터 필터 색인 을 만 드 는 것 에 대해 이야기 해 왔 습 니 다.그러면 필터 색인 의 장점 을 만 드 는 조건 은 무엇 입 니까?
(1)비 집합 색인 을 통 해 만 들 수 있 습 니 다.
(2)보기 에 필터 색인 을 만 들 려 면 이 보 기 는 지속 적 인 보기 여야 합 니 다.
(3)전체 텍스트 인덱스 에 필터 인덱스 를 만 들 수 없습니다.
필터 인덱스 의 장점
(1)색인 유지 비용 감소:증가,삭제,변경 등 작업 에 대해 대가 가 그리 비 싸 지 않 습 니 다.색인 을 걸 러 내 는 재 구축 에 시간 이 많이 걸 리 지 않 기 때 문 입 니 다.
(2)저장 비용 감소:색인 을 걸 러 내 는 저장 공간 이 매우 작다.
(3)더욱 정확 한 통계:WHERE 조건 에서 필터 색인 을 만 드 는 것 이 전체 표 통계 결과 보다 더욱 정확 하 다.
(4)조회 성능 최적화:조회 계획 을 통 해 효율 성 을 알 수 있다.
여기까지 만 해도 색인 을 걸 러 내 는 장점 과 장점 이 하늘 로 치 켜 세 웠 다 는 것 이 단점 이다.
필터 인덱스 단점
가장 큰 단점 은 조회 조건 의 제한 이다.그 조회 조건 은 한정된다
<filter_predicate> ::=
<conjunct> [ AND <conjunct> ]
<conjunct> ::=
<disjunct> | <comparison>
<disjunct> ::=
column_name IN (constant ,...n)
필터 조건 은 AND,|,IN 에 한 정 됩 니 다.비교 조건 은{IS|IS NOT|=|<>|!그래서 다음 과 같이 LIKE 를 이용 하면 안 돼 요.
CREATE NONCLUSTERED INDEX [idxwhere_noncls_somevalue] ON dbo.TestData(RowID) INCLUDE(SomeValue,StartDate)
WHERE SomeValue LIKE 'JeffckyWang%'
아래 와 같이 할 수 있다
USE AdventureWorks2012
GO
CREATE NONCLUSTERED INDEX idx_SalesOrderDetail_ModifiedDate
ON Sales.SalesOrderDetail(ModifiedDate)
WHERE ModifiedDate >= '2008-01-01' AND ModifiedDate <= '2008-01-07'
GO
아래 와 같이 는 안 된다
CREATE NONCLUSTERED INDEX idx_SalesOrderDetail_ModifiedDate
ON Sales.SalesOrderDetail(ModifiedDate)
WHERE ModifiedDate = GETDATE()
GO
변수 가 필터 인덱스 에 미 치 는 영향
검색 조건 에서 직접 정 의 된 문자열 을 만 듭 니 다.다음 과 같 습 니 다.
CREATE NONCLUSTERED INDEX idxwhere_SalesOrderDetail_UnitPrice
ON Sales.SalesOrderDetail(UnitPrice)
WHERE UnitPrice > 1000
변 수 를 정의 한다 면 변 수 를 이용 하여 비교 하 는 것 은 어 떨 까요?우선 필터 색인 을 만 듭 니 다.
CREATE NONCLUSTERED INDEX idx_SalesOrderDetail_ProductID
ON Sales.SalesOrderDetail (ProductID)
WHERE ProductID = 870
변 수 를 이용 하여 검색 조건 과 비교 하여 필터 색인 을 강제로 사용 합 니 다(기본 값 으로 집합 색인)
USE AdventureWorks2012
GO
DECLARE @ProductID INT
SET @ProductID = 870
SELECT ProductID
FROM Sales.SalesOrderDetail WITH(INDEX([idx_SalesOrderDetail_ProductID]))
WHERE ProductID = @ProductID
실행 계획 을 조회 하 는 중 오류 가 발생 했 습 니 다.이때 OPTION 을 추가 하여 재 컴 파일 해 야 합 니 다.다음 과 같 습 니 다.
USE AdventureWorks2012
GO
DECLARE @ProductID INT
SET @ProductID = 870
SELECT ProductID
FROM Sales.SalesOrderDetail
WHERE ProductID = @ProductID
OPTION(RECOMPILE)
상기 변 수 를 이용 하여 마지막 으로 OPTION 을 통 해 SQL Server 2012 에 재 컴 파일 하여 테스트 할 수 있 습 니 다.다른 버 전 은 알 수 없 으 며 참고 자료[The Pains of Filtered Indexes].
총결산
이 절 에서 우 리 는 색인 을 걸 러 서 조회 성능 을 향상 시 키 는 동시에 서로 다른 장면 과 그 사용 장점 과 뚜렷 한 단점 도 제시 했다.짧 은 내용,깊 은 이해,우리 다음 절 에 다시 만 나 자,good night.
이상 은 본 고의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 댓 글 을 남 겨 서 교류 할 수 있 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
깊이 중첩된 객체를 정확히 일치 검색 - PostgreSQL목차 * 🚀 * 🎯 * 🏁 * 🙏 JSON 객체 예시 따라서 우리의 현재 목표는 "고용주"사용자가 입력한 검색어(이 경우에는 '요리')를 얻고 이 용어와 정확히 일치하는 모든 사용자 프로필을 찾는 것입니다. 즐거운 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.