繁体   English   中英

SQL Server:查询性能分析-是否有优化想法?

[英]SQL Server : Query performance analysis - Any Optimization ideas?

我已经阅读了多篇推荐使用SQL Server Profiler的文章,我也是。

我有一个非常重要的查询,它会使应用程序不时冻结。 该查询包括多个LEFT JOIN ... ON ... AND (... AND ...) OR (... AND ...)

我对正在使用的关系模型没有任何权限,因此我必须使用它。

该查询是关于在发生火灾时将附近的危险产品放置在附近,以帮助制定消防人员干预计划的。 该查询有效,只需要进行一些优化即可。

现在,我有这个查询有6635 Reads296 CPU0 Writes281 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM