긴급하지 않고 주문 상태 = 1 (배송 됨) 인 모든 주문을 계산하고 싶습니다.필터 된 인덱스를 힌트로 일정한 속도를 얻기 위해 SELECT COUNT (*) 쿼리를 최적화 할 수 있습니까?
최적화를위한 매우 간단한 쿼리 여야합니다. Orders 테이블에 간단한 필터링 된 인덱스를 넣어이 쿼리가 일정한 시간/O (1) 작업을 수행하도록하고 싶습니다. 그러나 쿼리 계획을 살펴보면 인덱스 스캔을 사용하는 것 같아 이해가되지 않습니다. 이상적으로이 쿼리는 인덱스의 항목 수만 반환해야합니다.
(본질에 도착 간체) 같은 테이블보기 :이 쿼리를 수행 할 때, 이제
CREATE INDEX IX_Orders_ShippedNonUrgent ON Orders(Id) WHERE IsUrgent = 0 AND Status = 1;
: :이 필터링 된 인덱스를 만들었습니다
CREATE TABLE [dbo].[Orders](
[Id] [int] IDENTITY(1,1) NOT NULL,
[IsUrgent] [bit] NOT NULL,
[Status] [tinyint] NOT NULL
CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED ([Id] ASC)
SELECT COUNT(*) FROM Orders WHERE IsUrgent = 0 AND Status = 1
쿼리 계획에서 IX_Orders_ShippedNonUrgent를 사용하고 있지만 색인 스캔을 수행하고 있습니다. 주문에서 ~ 200,000 개의 행을 읽습니다.
필터링 된 색인이 최신 상태로 유지된다고 가정하면 일정 시간 내에 항상이 쿼리를 실행할 수 있습니까? 인덱스의 크기를 얻으려면 읽기를 한 번만 수행하는 것이 가장 이상적입니다.
CREATE INDEX IX_Orders_IsUrgentStatus ON Orders(IsUrgent, Status);
쿼리 계획은 인덱스 탐색 사용하지만, 여전히 많은이 간단한 쿼리에 응답 할 필요가있을 것보다 읽기를 수행 :이 같은 비 필터링 된 인덱스로 전환하면
.
UPDATE 나는 9 읽기에 결과를이
SELECT TOP 1 rows FROM sys.partitions p
INNER JOIN sys.indexes i
ON i.name = 'IX_Orders_ShippedNonUrgent'
AND i.object_id = p.object_id
AND i.index_id = p.index_id
을 얻을 수 있어요하지만 간단한을 사용하는 훨씬 쉽고 덜 부서지기 쉬운 방법이 있어야한다 것 같다
COUNT (*) 쿼리.
카운트 (*)를 읽기 카운트 (id)로 변경하면 어떤 변화가 있습니까? 또는 Materialized View를 고려 했습니까? –
COUNT (*)에서 COUNT (ID)로 전환해도 계획이나 읽기에는 영향을주지 않습니다. 보기 확인 중 ... –
나는 "CREATE VIEW VW_Orders_Test AS SELECT COUNT (1) IsUrgent = 0 AND Status = 1"에서 동일한 쿼리 계획을 가지고 있으며 읽음 –