문제

다음 합성 클러스터 된 인덱스를 고려하십시오.

CREATE UNIQUE CLUSTERED INDEX ix_mytable ON mytable(a, b)

분명히, 별도의 색인 특정 값을 검색 할 것입니다 더 빠르게.

그러나 별도의 색인이 켜져있는 경우 ~이다 ~ 아니다 사용 된 것은 복합 지수가 여전히 특정 값을 가진 튜플을 찾는 데 사용될 수있는 것 같습니다. 이산 값의 트리를 통과하여 테이블 스캔 대신 그리고 현지 검색을하십시오 , 다음 값으로 점프하십시오 , 등.

이것이 SQL Server의 작동 방식입니까? (예를 들어 MSSQL이 여러 열이있는 인덱스에 단일 해시 값을 사용하는 경우에는 그렇지 않습니다.)

그것은 다른 이유로 이미 복합 지수와 이산 값의 수가 필요합니다. 충분히 작기 때문에 성능/우주 트레이드 오프는 별도의 인덱스를 갖지 못할 수 있습니다. .

(위의 고유하고 클러스터 된 제약 조건은이 예에 실제로 필요하지 않지만 가장 빠른 검색을 나타냅니다. 그것은 별도의 색인이 포함되지 않았습니다 -전자는 각 루프에 대한 바로 가기를 제공합니다 , 후자는 조회에서 1 도의 간접을 제거합니다).

도움이 되었습니까?

해결책

아니요, 'A'의 클러스터 위에 점프하지 않습니다. 가장 왼쪽 열이 지정된 경우에만 인덱스를 사용할 수 있습니다. 그렇지 않으면 전체 스캔을 사용해야합니다.

오라클은 소위 호출을 가지고 있습니다 '인덱스 스킵 스캔' 운영자.

다른 팁

USE AdventureWorks2008R2;
-- Source: http://msftdbprodsamples.codeplex.com/releases/view/59211
GO

SET NOCOUNT ON;
GO

CREATE NONCLUSTERED INDEX IX_SalesOrderHeader_OrderDate_#_ShipDate_SubTotal
ON [Sales].[SalesOrderHeader] ([OrderDate])
INCLUDE (ShipDate,SubTotal)
-- WITH(DROP_EXISTING=ON);
GO

-- Test 1
SET STATISTICS IO ON;
SELECT  COUNT(*)
FROM    Sales.SalesOrderHeader h -- Index Seek on IX_SalesOrderHeader_OrderDate_#_ShipDate_SubTotal
WHERE   h.OrderDate BETWEEN '2008-07-01T00:00:00.000' AND '2008-07-15T23:59:59.997';
SET STATISTICS IO OFF;
GO
-- End of Test 1
-- Results:
-- Table 'SalesOrderHeader'. Scan count 1, logical reads 5, physical reads 0

DROP INDEX IX_SalesOrderHeader_OrderDate_#_ShipDate_SubTotal
ON [Sales].[SalesOrderHeader]
GO
CREATE NONCLUSTERED INDEX [IX_SalesOrderHeader_ShipMethodID_OrderDate_#_ShipDate_SubTotal] 
ON Sales.SalesOrderHeader 
(
    ShipMethodID ASC,
    OrderDate ASC
)
INCLUDE (ShipDate,SubTotal);
GO

-- Test 2
SET STATISTICS IO ON;
SELECT  COUNT(*)
FROM    Sales.SalesOrderHeader h -- Index Scan on IX_SalesOrderHeader_ShipMethodID_OrderDate_#_ShipDate_SubTotal
WHERE   h.OrderDate BETWEEN '2008-07-01T00:00:00.000' AND '2008-07-15T23:59:59.997';
SET STATISTICS IO OFF;
GO
-- End of Test 2
-- Results:
-- Table 'SalesOrderHeader'. Scan count 1, logical reads 150, physical reads 0

-- Test 3
SET STATISTICS IO ON;
SELECT  COUNT(*)
FROM    Purchasing.ShipMethod sm
INNER JOIN Sales.SalesOrderHeader h ON h.ShipMethodID=sm.ShipMethodID -- FK elimination + Index Scan on IX_SalesOrderHeader_ShipMethodID_OrderDate_#_ShipDate_SubTotal
WHERE   h.OrderDate BETWEEN '2008-07-01T00:00:00.000' AND '2008-07-15T23:59:59.997';
SET STATISTICS IO OFF;
GO
-- End of Test 3
-- Results:
-- Table 'SalesOrderHeader'. Scan count 1, logical reads 150, physical reads 0

-- Test 4
SET STATISTICS IO ON;
SELECT  MIN(sm.ShipMethodID) AS DummnyCol, -- To prevent FK elimination 
        COUNT(*)
FROM    Purchasing.ShipMethod sm
INNER JOIN Sales.SalesOrderHeader h ON h.ShipMethodID=sm.ShipMethodID -- Index Seek on IX_SalesOrderHeader_ShipMethodID_OrderDate_#_ShipDate_SubTotal
WHERE   h.OrderDate BETWEEN '2008-07-01T00:00:00.000' AND '2008-07-15T23:59:59.997';
SET STATISTICS IO OFF;
GO
-- End of Test 4
-- Results:
-- Table 'SalesOrderHeader'. Scan count 5, logical reads 13, physical reads 0
-- Table 'ShipMethod'. Scan count 1, logical reads 2, physical reads 0

DROP INDEX [IX_SalesOrderHeader_ShipMethodID_OrderDate_#_ShipDate_SubTotal] 
ON Sales.SalesOrderHeader;
GO
SET NOCOUNT OFF;
GO
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top