问题描述
我对这只狗的结尾感到沮丧,因为我确信这很简单,并且我需要另一双眼睛。我尝试了几种不同的方法,但仍然遇到问题,该查询将运行整整24小时而没有结果...
我将问题缩小到查询的这一部分:
WHERE sub.[Savings (%)] >= 10
我遇到了很多问题,最终我将整个查询嵌套到一个子查询中,试图将我的大部分计算都从“ Where”子句中删除,但是没有效果。
这都是更大的查询的一部分,因此我将发布相关的缩写部分。
这是查询的最开始:
SELECT *
FROM
(
SELECT
LD.Region,DM.ShortName AS DM,D.Lcode,LD.locationname,D.UnitID,D.dplaced,D.dCancelled,D.sRentalType,D.[Quoted Rate],Calcs.MinStdrate AS [Current Rate],-(Calcs.MinStdrate - D.[Quoted Rate]) AS [Savings ($)],((-(Calcs.MinStdrate - D.[Quoted Rate]))/NULLIF(D.[Quoted Rate],0))*100 AS [Savings (%)],D.sPlanName,Calcs.[# Vacant]
FROM...
然后这是导致问题的查询末尾的WHERE子句。 “ SELECT * FROM”下面的整个查询(如上所示)称为“ Sub”:
) AS sub
WHERE sub.[Savings (%)] >= 10
AND sub.[Current Rate] <> 0
AND sub.[Quoted Rate] <> 0
当我在查询中注明“ sub。[Savings(%)]> = 10 AND”时,整个过程耗时约5秒钟。有了它,它会连续运行几个小时,而且永远不会产生结果...
我想念什么?
SELECT *
FROM
(
SELECT
LD.Region,CAST(((-(Calcs.MinStdrate - D.[Quoted Rate]))/NULLIF(D.[Quoted Rate],0))*100 AS DECIMAL (18,2)) AS [Savings (%)],Calcs.[# Vacant]
FROM
(SELECT
s.sLocationCode AS lcode,w.dplaced,L.dLease,u.UnitID,CASE
WHEN w.dCancelled IS NOT NULL THEN w.dCancelled
WHEN (w.dCancelled IS NULL AND w.dExpires <GETDATE()) THEN w.dExpires
ELSE NULL
END AS dCancelled,CASE
WHEN (w.dCancelled IS NOT NULL OR w.dExpires <GETDATE()) THEN 'Lost'
WHEN w.QTRentalTypeID = 3 THEN 'Rented'
WHEN (w.QTRentalTypeID = 2 OR w.QTRentalTypeID = 1) THEN 'Active'
END AS sRentalType,w.dcRate_Quoted AS 'Quoted Rate',c.sPlanName,CONCAT(U.dcWidth,'x',U.dcLength) AS sSize,UT.sTypeName
FROM CompanyDBs.dbo.waitings AS W
LEFT OUTER JOIN CompanyDBs.dbo.Ledgers AS L
ON W.LedgerID = L.LedgerID
JOIN CompanyDBs.dbo.sites AS S
ON W.SiteID = S.SiteID
JOIN CompanyDBs.dbo.units AS U
ON W.UnitID1 = U.UnitID
JOIN CompanyDBs.dbo.UnitTypes AS UT
ON U.UnitTypeID = UT.UnitTypeID
JOIN CompanyDBs.dbo.ConcessionPlans AS C
ON W.ConcessionID = C.ConcessionID
WHERE W.dCancelled < GETDATE() AND W.dCancelled >= DATEADD(DD,-60,CAST(GETDATE() AS DATE))
UNION ALL
SELECT
s.sLocationCode AS lcode,UT.sTypeName
FROM CompanyDBs1.dbo.waitings AS W
LEFT OUTER JOIN CompanyDBs1.dbo.Ledgers AS L
ON W.LedgerID = L.LedgerID
JOIN CompanyDBs1.dbo.sites AS S
ON W.SiteID = S.SiteID
JOIN CompanyDBs1.dbo.units AS U
ON W.UnitID1 = U.UnitID
JOIN CompanyDBs1.dbo.UnitTypes AS UT
ON U.UnitTypeID = UT.UnitTypeID
JOIN CompanyDBs1.dbo.ConcessionPlans AS C
ON W.ConcessionID = C.ConcessionID
WHERE W.dCancelled < GETDATE() AND W.dCancelled >= DATEADD(DD,CAST(GETDATE() AS DATE))) AS D
LEFT OUTER JOIN
(SELECT
P.SiteID,P.sLocationCode,P.UnitID,p.UnitCODE,groupeddata.[# Vacant],GroupedData.MinStdrate
FROM
(SELECT
S2.sLocationCode,S2.SiteID,R2.UnitID,CONCAT(S2.sLocationCode,'-',S2.sSiteName,' ',R2.stypename,CASE WHEN R2.iFloor > 1 THEN 'Up ' WHEN R2.ifloor < 1 THEN 'Down ' WHEN R2.ifloor = 1 THEN '1 ' END,CASE WHEN R2.bPower = 1 THEN 'Power ' ELSE 'No Power ' END,CASE WHEN R2.bclimate = 1 THEN 'CC ' ELSE 'No CC ' END,CASE WHEN R2.bInside = 1 THEN 'In ' ELSE 'Out ' END,CASE WHEN R2.bAlarm = 1 THEN 'Alarm ' ELSE 'No Alarm ' END,CAST(R2.dcWidth AS FLOAT),CAST(R2.dcLength AS FLOAT)) AS UnitCODE
FROM Operations.dbo.RentRoll AS R2
JOIN
(
SELECT *
FROM CompanyDBs.dbo.sites
UNION ALL
SELECT *
FROM CompanyDBs1.dbo.sites
) AS S2
ON R2.siteid = S2.SiteID
WHERE
R2.ddeleted is NULL
AND R2.bRentable = 1
AND R2.brented = 0 ) AS P
JOIN
(
SELECT
S.SiteID,s.sLocationCode,UnitCode.UnitCODE,SUM(CASE
WHEN R.brented = 1 THEN 0
ELSE 1
END) AS [# Vacant],MIN(R.dcStdrate) AS MinStdrate
FROM Operations.dbo.RentRoll AS R
JOIN
(
SELECT *
FROM CompanyDBs.dbo.sites
UNION ALL
SELECT *
FROM CompanyDBs1.dbo.sites
) AS S
ON R.siteid = S.SiteID
JOIN
(
SELECT
S1.SiteID,UnitID,CONCAT(S1.sLocationCode,S1.sSiteName,R1.stypename,CASE WHEN R1.iFloor > 1 THEN 'Up ' WHEN R1.ifloor < 1 THEN 'Down ' WHEN R1.ifloor = 1 THEN '1 ' END,CASE WHEN R1.bPower = 1 THEN 'Power ' ELSE 'No Power ' END,CASE WHEN R1.bclimate = 1 THEN 'CC ' ELSE 'No CC ' END,CASE WHEN R1.bInside = 1 THEN 'In ' ELSE 'Out ' END,CASE WHEN R1.bAlarm = 1 THEN 'Alarm ' ELSE 'No Alarm ' END,CAST(R1.dcWidth AS FLOAT),CAST(R1.dcLength AS FLOAT)) AS UnitCODE
FROM Operations.dbo.RentRoll AS R1
JOIN
(
SELECT *
FROM CompanyDBs.dbo.sites
UNION ALL
SELECT *
FROM CompanyDBs1.dbo.sites
) AS S1
ON R1.siteid = S1.SiteID
) AS UnitCode
ON CONCAT(R.siteid,R.unitid) = CONCAT(UnitCode.siteid,UnitCode.UnitID)
WHERE
s.sLocationCode <> 'L003'
AND s.sLocationCode <> 'L021'
AND s.sLocationCode <> 'LSETUP'
AND s.sLocationCode <> 'LTRAIN'
AND R.bRented = 0
GROUP BY s.siteid,s.slocationcode,UnitCode.UnitCODE
) AS GroupedData
ON P.UnitCODE = GroupedData.UnitCODE
) AS Calcs
ON CONCAT(D.lcode,D.unitid) = CONCAT(Calcs.slocationcode,Calcs.unitid)
JOIN operations.dbo.westport_locationdata AS LD
ON D.lcode = ld.lcode
JOIN operations.dbo.Westport_DMs AS DM
ON LD.DMID = DM.DMID
) AS sub
WHERE sub.[Savings (%)] >= CAST(10.0 AS DECIMAL (18,2))
AND sub.[Current Rate] <> 0
AND sub.[Quoted Rate] <> 0
解决方法
很遗憾,您发布的不是整个查询。我可以想象有些索引丢失了。
我强烈建议您在SQL Server Management Studio中运行查询,并选中“查询”->“包括实际执行计划”。
使用此方法,SSMS将执行查询并随后告诉您索引是否丢失以及通过设置索引可以提高多少。您还将获得一张图片,查询的运行方式。
,投射您的where子句过滤器值WHERE sub.[Savings (%)] >= cast(10.0 as decimal(18,2))
,这样就不会从int
到decimal
进行隐式转换。