我已阅读多篇推荐使用SQL Server Profiler的文章,我也是。
我有一个非常重要的查询,它会使应用程序不时冻结。该查询包含多个LEFT JOIN ... ON ... AND (... AND ...) OR (... AND ...)
。
我对正在使用的关系模型没有权限,所以我必须使用它。
该询问是关于在发生火灾时附近的危险品附近,以帮助计划消防员干预计划。查询有效,只需要进行一些优化。
现在,我的此查询包含6635 Reads
,296 CPU
,0 Writes
,281 Duration
。
我能想到的只是查询太慢而且可能太重而服务器无法执行。换句话说,它根本不是最优的。
如果重要,因为我相信它,查询在其where子句中有多个计算,如:
ATN2(SQRT(SIN(RADIANS(@latitude - CASE WHEN LocationType = @locationType THEN Buildings.Latitude ELSE Intersections.Latitude END) / 2 *...
我没有预算购买工具或其他任何工具。
更新
根据要求,这是一个可怕的查询:
SELECT PHM.ID, HP.Name, PHMD.TL, PHMD.QTY
, PHMD.CT, PHMD.C, PHMD.MU
, HP.HR, HP.FR, HP.RR, HP.SR
, PHMD.CP
, A.HN, A.Alpha
, CASE WHEN PHM.LT <> @7 THEN TL.D ELSE TL.D + ' ' + TL2.D END AS TLcol
, C.D AS CD
FROM PHM
LEFT JOIN PHMD ON PHMD.ExID = PHM.ID
LEFT JOIN HP ON PHMD.HPID = HP.ID
LEFT JOIN BP ON PHM.LT=@5
AND BP.ID = PHM.BPID
LEFT JOIN A ON (PHM.LT=@4
AND A.ID = PHM.AID)
OR (PHM.LT=@5
AND BP.AID = A.ID)
LEFT JOIN I ON I.ID = PHM.IID
LEFT JOIN TL ON (PHM.LT<>@7
AND A.TLID = TL.ID)
OR (PHM.LT=@7
AND I.TLID1 = TL.ID)
LEFT JOIN TL AS TL2 ON PHM.LT=@7
AND I.TLID2 = TL2.ID
LEFT JOIN C ON TL.CID=C.ID
LEFT JOIN B ON A.ID = B.ExID
LEFT JOIN B ON B.ID = B.BID
WHERE EXISTS (SELECT * FROM PHMD WHERE PHMD.ExID=PHM.ID)
AND (((PHM.LT=@4 AND PHM.AID=@8)
OR (PHM.LT=@5 AND PHM.BPID IN (SELECT ID FROM BP WHERE AID=@8))
OR (PHM.LT=@6 AND PHM.BID IN (SELECT BID FROM B WHERE ExID=@8)))
AND PHM.DV = (
SELECT MAX(PHMLD.DV)
FROM PHM AS PHMLD
WHERE PHMLD.LT = PHM.LT
AND ISNULL(PHMLD.AddressID,0) = ISNULL(PHM.AID,0)
AND ISNULL(PHMLD.SuiteID,0) = ISNULL(PHM.SID,0)
AND ISNULL(PHMLD.BPID,0) = ISNULL(PHM.BPID,0)
AND ISNULL(PHMLD.IID,0)=ISNULL(PHM.IID,0)
AND ISNULL(PHMLD.BID,0)=ISNULL(PHM.BID,0))
OR 6371010 * (2 * ATN2(
SQRT((SIN(RADIANS(@1 - CASE WHEN PHM.LT<>@6 THEN B.LAT ELSE I.LAT END)/2)
* SIN(RADIANS(@1 - CASE WHEN PHM.LT<>@6 THEN B.LAT ELSE I.LAT END)/2)
+ COS(RADIANS(CASE WHEN PHM.LT<>@6 THEN B.LAT ELSE I.LAT END))
* COS(RADIANS(@1))
* SIN(RADIANS(@2 - CASE WHEN PHM.LT<>@6 THEN B.LNG ELSE I.LNG END)/2)
* SIN(RADIANS(@2 - CASE WHEN PHM.LT<>@6 THEN B.LNG ELSE I.LNG END)/2)))
, SQRT(1-(SIN(RADIANS(@1 - CASE WHEN PHM.LT<>@6 THEN B.LAT ELSE I.LAT END)/2)
* SIN(RADIANS(@1 - CASE WHEN PHM.LT<>@6 THEN B.LAT ELSE I.LAT END)/2)
+ COS(RADIANS(CASE WHEN PHM.LT<>@6 THEN B.LAT ELSE I.LAT END))
* COS(RADIANS(@1))
* SIN(RADIANS(@2 - CASE WHEN PHM.LT<>@6 THEN B.LNG ELSE I.LNG END)/2)
* SIN(RADIANS(@2 - CASE WHEN PHM.LT<>@6 THEN B.LNG ELSE I.LNG END)/2))))
) <= @3)
SET SHOWPLAN_XML ON
更新
请访问以下链接以了解执行showplan。 http://pastebin.com/k6GxxSKF
谢谢你的帮助! =)
答案 0 :(得分:1)
查看查询执行计划我可以看到花费在LEFT OUTER
联接上的时间最多。查询计划显示73%的查询时间/资源花费在该一个联接上。
你需要左外连接吗?
大多数查询都使用索引查找并返回非常少的行,这些行尽可能好。但是,他们使用NESTED LOOP
连接,这不是最有效的JOIN类型。我怀疑如果您强制使用MERGE
甚至HASH
联接类型,您可能会看到不同的性能。有关如何强制使用其他类型的JOIN
,请参阅this link。但这并不是真的值得推荐的。
这些表经常更新吗?还是他们非常静止?这些表中还有多少数据。我怀疑如果SQL服务器使用错误的JOIN类型,那么表上的统计信息可能已过期。尝试在表上运行UPDATE STATISTICS
并检查查询计划是否更改。