Tôi muốn biết cách tiếp cận nào trong hai cách sau nhanh hơn:
1) Ba COUNT
:
SELECT Approved = (SELECT COUNT(*) FROM dbo.Claims d
WHERE d.Status = 'Approved'),
Valid = (SELECT COUNT(*) FROM dbo.Claims d
WHERE d.Status = 'Valid'),
Reject = (SELECT COUNT(*) FROM dbo.Claims d
WHERE d.Status = 'Reject')
2) SUM
với FROM
-cách:
SELECT Approved = SUM(CASE WHEN Status = 'Approved' THEN 1 ELSE 0 END),
Valid = SUM(CASE WHEN Status = 'Valid' THEN 1 ELSE 0 END),
Reject = SUM(CASE WHEN Status = 'Reject' THEN 1 ELSE 0 END)
FROM dbo.Claims c;
Tôi đã ngạc nhiên rằng sự khác biệt là rất lớn. Truy vấn đầu tiên với ba truy vấn con trả về kết quả ngay lập tức trong khi SUM
cách tiếp cận thứ hai cần 18 giây.
Claims
là một khung nhìn chọn từ một bảng chứa ~ 18 triệu hàng. Có một chỉ mục trên Cột FK cho ClaimStatus
bảng chứa tên trạng thái.
Tại sao nó làm cho một sự khác biệt lớn như vậy cho dù tôi sử dụng COUNT
hay SUM
?
Kế hoạch thực hiện:
Có tổng cộng 12 trạng thái. Ba trạng thái này thuộc về 7% của tất cả các hàng.
Đây là chế độ xem thực tế, tôi không chắc nó có liên quan hay không:
CREATE VIEW [dbo].[Claims]
AS
SELECT
mu.Marketunitname AS MarketUnit,
c.Countryname AS Country,
gsp.Gspname AS GSP,
gsp.Wcmskeynumber AS GspNumber,
sl.Slname AS SL,
sl.Wcmskeynumber AS SlNumber,
m.Modelname AS Model,
m.Salesname AS [Model-Salesname],
s.Claimstatusname AS [Status],
d.Work_order AS [Work Order],
d.Ssn_number AS IMEI,
d.Ssn_out,
Remarks,
d.Claimnumber AS [Claim-Number],
d.Rma_number AS [RMA-Number],
dbo.ToShortDateString(d.Received_Date, 1) AS [Received Date],
Iddata,
Fisl,
Fimodel,
Ficlaimstatus
FROM Tabdata AS d
INNER JOIN Locsl AS sl
ON d.Fisl = sl.Idsl
INNER JOIN Locgsp AS gsp
ON sl.Figsp = gsp.Idgsp
INNER JOIN Loccountry AS c
ON gsp.Ficountry = c.Idcountry
INNER JOIN Locmarketunit AS mu
ON c.Fimarketunit = mu.Idmarketunit
INNER JOIN Modmodel AS m
ON d.Fimodel = m.Idmodel
INNER JOIN Dimclaimstatus AS s
ON d.Ficlaimstatus = s.Idclaimstatus
INNER JOIN Tdefproducttype
ON d.Fiproducttype = Tdefproducttype.Idproducttype
LEFT OUTER JOIN Tdefservicelevel
ON d.Fimaxservicelevel = Tdefservicelevel.Idservicelevel
LEFT OUTER JOIN Tdefactioncode AS ac
ON d.Fimaxactioncode = ac.Idactioncode
Authorized
.
WHERE c.Status = 'Approved' or c.Status = 'Valid' or c.status = 'Reject'
vào SUM
biến thể.
COUNT
phiên bản của kế hoạch. Bạn có thể chỉnh sửa like choSUM
phiên bản để chỉ ra kế hoạch chính xác không?