[英]SQL Server : Query performance analysis - Any Optimization ideas?
我已经阅读了多篇推荐使用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 *...
我没有预算购买任何工具。
UPDATE
根据请求,这是可怕的查询:
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
更新中SET SHOWPLAN_XML ON
请访问以下链接获取执行展示计划。 http://pastebin.com/k6GxxSKF
多谢您的协助! =)
查看查询执行计划,我可以看到在LEFT OUTER
联接上花费的时间最多。该查询计划显示73%的查询时间/资源花费在该联接上。
您是否需要左外部连接?
大多数查询使用索引查找并返回很少的行,这与它获得的一样好。 但是,他们使用的是NESTED LOOP
连接,这不是最有效的JOIN类型。 我怀疑如果您强制使用MERGE
甚至HASH
类型,您可能会看到不同的性能。 有关如何强制另一种JOIN
请参见此链接 。 不过,实际上并不建议这样做。
这些表是否经常更新? 还是它们很静态? 这些表中还有多少数据。 我怀疑如果SQL Server使用错误的JOIN类型,则可能是表上的统计信息已过时。 尝试在表上运行UPDATE STATISTICS
,并检查查询计划是否更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.