2

긴급하지 않고 주문 상태 = 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 (*) 쿼리.

+1

카운트 (*)를 읽기 카운트 (id)로 변경하면 어떤 변화가 있습니까? 또는 Materialized View를 고려 했습니까? –

+0

COUNT (*)에서 COUNT (ID)로 전환해도 계획이나 읽기에는 영향을주지 않습니다. 보기 확인 중 ... –

+0

나는 "CREATE VIEW VW_Orders_Test AS SELECT COUNT (1) IsUrgent = 0 AND Status = 1"에서 동일한 쿼리 계획을 가지고 있으며 읽음 –

답변

1

내가 원했던 것처럼 보이지 않는 것 같습니다.

CREATE UNIQUE CLUSTERED INDEX IX_vw_Orders_TotalShippedNonUrgent ON vw_Orders_TotalShippedNonUrgent(TotalOrders); 

CREATE VIEW [dbo].vw_Orders_TotalShippedNonUrgent WITH SCHEMABINDING 
AS 
SELECT COUNT_BIG(*) AS TotalOrders 
    FROM dbo.Orders WHERE IsUrgent = 0 AND Status = 1; 

각 요약에 대한 전망과 인덱스를 만드는이 힘 : 가장 좋은 대답 대신 인덱싱 된 뷰를 필터링 된 인덱스에 대해 잊고 사용되는 Nikola Markovinović에 의해 코멘트에 남아 있었다 통계뿐만 아니라 간단한 접근 방식 대신보기를 묻기 위해 쿼리를 다시 작성하지만, 단 2 번의 읽기만으로도 빠릅니다.

아무도 간단한 접근 방식을 사용하는 경우를 대비하여이 질문을 잠시 열어 두겠습니다.