我想知道以下两种方法中哪一种速度更快:
1)三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
与FROM
-clause:
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;
令我惊讶的是差异如此之大。具有三个子查询的第一个查询立即返回结果,而第二种SUM
方法则需要18秒。
Claims
是从包含约1800万行的表中选择的视图。该ClaimStatus
表的FK列上有一个索引,其中包含状态名称。
无论我使用COUNT
还是使用它,为什么会有如此大的不同SUM
?
执行计划:
共有12个状态。这三个状态占所有行的7%。
这是实际视图,我不确定是否相关:
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
具有这三个状态的行与具有其他状态的行的比率是多少?
—
Max Vernon
@MaxVernon:是的,当然,我看过太多零,你是对的。让我删除我的评论。是的,其他状态的行数为1670万。大多数是
—
蒂姆·施密特
Authorized
。
我估计第二个计划将不得不扫描整个表12次(即显示的结果)。这可能是由于无法将谓词下推到扫描中而引起的。如果添加
—
Max Vernon
WHERE c.Status = 'Approved' or c.Status = 'Valid' or c.status = 'Reject'
到SUM
变体,性能如何?
@MaxVernon:共有十二种状态。对我来说,这不是真正的问题,但是我很惊讶优化器无法处理此问题。我应该真正地执行我的执行计划分析技能。做出答案。您的假设是什么,为什么SQL Server无法仅扫描三种状态?
—
蒂姆·施密特
COUNT
该计划的版本。您可以将like修改为SUM
版本以指向正确的计划吗?