在sql server中外部应用使我的查询工作缓慢

时间:2016-12-23 14:06:45

标签: sql-server performance

我有这个查询

select *
from    joints c

执行时间为14秒。每个关节行都有一个id。我应该将此id传递给另一个查询以获取其他信息,如您所见:

SELECT    top 1    dbo.NdtReportDetails.RequestNumber AS MasterRTRequestNumber, dbo.NdtReports.NdtReportNumber AS ContractorRTRequestNumber,NdtReportDetails.ResponseReportDatetime AS RTDate, NdtReportDetails.Defect as RTDefect,
                         dbo.NdtReportDetails.ResponseReportNumber AS ContractorRTReportNumber,NdtReportDetails.Remark as RTSegment
FROM            dbo.NdtReportDetails LEFT OUTER JOIN
                         dbo.NdtReports ON dbo.NdtReportDetails.ReportId = dbo.NdtReports.Id 
        where NdtReportDetails.JointId=c.Id  and NdtReportDetails.NdtType='RT'  order by NdtReportDetails.Id desc

所以最后的查询:

select *


from    joints c
    outer  Apply 
    (SELECT    top 1    dbo.NdtReportDetails.RequestNumber AS MasterRTRequestNumber, dbo.NdtReports.NdtReportNumber AS ContractorRTRequestNumber,NdtReportDetails.ResponseReportDatetime AS RTDate, NdtReportDetails.Defect as RTDefect,
                         dbo.NdtReportDetails.ResponseReportNumber AS ContractorRTReportNumber,NdtReportDetails.Remark as RTSegment
FROM            dbo.NdtReportDetails LEFT OUTER JOIN
                         dbo.NdtReports ON dbo.NdtReportDetails.ReportId = dbo.NdtReports.Id 
        where NdtReportDetails.JointId=c.Id  and NdtReportDetails.NdtType='RT'  order by NdtReportDetails.Id desc) b


        outer  Apply 
    (SELECT    top 1    dbo.NdtReportDetails.RequestNumber AS MasterRTRequestNumber, dbo.NdtReports.NdtReportNumber AS ContractorRTRequestNumber,NdtReportDetails.ResponseReportDatetime AS RTDate, NdtReportDetails.Defect as RTDefect,
                         dbo.NdtReportDetails.ResponseReportNumber AS ContractorRTReportNumber,NdtReportDetails.Remark as RTSegment
FROM            dbo.NdtReportDetails LEFT OUTER JOIN
                         dbo.NdtReports ON dbo.NdtReportDetails.ReportId = dbo.NdtReports.Id 
        where NdtReportDetails.JointId=c.Id  and NdtReportDetails.NdtType='PT'  order by NdtReportDetails.Id desc) d

    outer  Apply 
    (SELECT    top 1    dbo.NdtReportDetails.RequestNumber AS MasterRTRequestNumber, dbo.NdtReports.NdtReportNumber AS ContractorRTRequestNumber,NdtReportDetails.ResponseReportDatetime AS RTDate, NdtReportDetails.Defect as RTDefect,
                         dbo.NdtReportDetails.ResponseReportNumber AS ContractorRTReportNumber,NdtReportDetails.Remark as RTSegment
FROM            dbo.NdtReportDetails LEFT OUTER JOIN
                         dbo.NdtReports ON dbo.NdtReportDetails.ReportId = dbo.NdtReports.Id 
        where NdtReportDetails.JointId=c.Id  and NdtReportDetails.NdtType='PWHT'  order by NdtReportDetails.Id desc) m


        outer  Apply 
    (SELECT    top 1    dbo.NdtReportDetails.RequestNumber AS MasterRTRequestNumber, dbo.NdtReports.NdtReportNumber AS ContractorRTRequestNumber,NdtReportDetails.ResponseReportDatetime AS RTDate, NdtReportDetails.Defect as RTDefect,
                         dbo.NdtReportDetails.ResponseReportNumber AS ContractorRTReportNumber,NdtReportDetails.Remark as RTSegment
FROM            dbo.NdtReportDetails LEFT OUTER JOIN
                         dbo.NdtReports ON dbo.NdtReportDetails.ReportId = dbo.NdtReports.Id 
        where NdtReportDetails.JointId=c.Id  and NdtReportDetails.NdtType='MT'  order by NdtReportDetails.Id desc) o

        outer  Apply 
    (SELECT    top 1    dbo.NdtReportDetails.RequestNumber AS MasterRTRequestNumber, dbo.NdtReports.NdtReportNumber AS ContractorRTRequestNumber,NdtReportDetails.ResponseReportDatetime AS RTDate, NdtReportDetails.Defect as RTDefect,
                         dbo.NdtReportDetails.ResponseReportNumber AS ContractorRTReportNumber,NdtReportDetails.Remark as RTSegment
FROM            dbo.NdtReportDetails LEFT OUTER JOIN
                         dbo.NdtReports ON dbo.NdtReportDetails.ReportId = dbo.NdtReports.Id 
        where NdtReportDetails.JointId=c.Id  and NdtReportDetails.NdtType='UT'  order by NdtReportDetails.Id desc) u
        order by c.Id

执行时间是45秒。那么有什么更好的解决方案可以让这个查询更快地运行吗? enter image description here

我正在使用索引来提高性能。

我的查询

SELECT *
FROM   dbo.JointHistory c
       OUTER Apply (SELECT TOP 1 WITH ties 
                           Max(CASE NRD.NdtType WHEN 'RT' THEN NRD.RequestNumber END) AS RT_MasterRTRequestNumber,
                           Max(CASE NRD.NdtType WHEN 'RT' THEN NR.NdtReportNumber END) AS RT_ContractorRTRequestNumber,
                           Max(CASE NRD.NdtType WHEN 'RT' THEN NRD.ResponseReportDatetime END) AS RT_RTDate,
                           Max(CASE NRD.NdtType WHEN 'RT' THEN NRD.Defect END) AS RT_RTDefect,
                           Max(CASE NRD.NdtType WHEN 'RT' THEN NRD.ResponseReportNumber END) AS RT_ContractorRTReportNumber,
                           Max(CASE NRD.NdtType WHEN 'RT' THEN NRD.Remark END) AS RT_RTSegment,
                           Max(CASE NRD.NdtType WHEN 'PT' THEN NRD.RequestNumber END) AS PT_MasterRTRequestNumber,
                           Max(CASE NRD.NdtType WHEN 'PT' THEN NR.NdtReportNumber END) AS PT_ContractorRTRequestNumber,
                           Max(CASE NRD.NdtType WHEN 'PT' THEN NRD.ResponseReportDatetime END) AS PT_RTDate,
                           Max(CASE NRD.NdtType WHEN 'PT' THEN NRD.Defect END) AS PT_RTDefect,
                           Max(CASE NRD.NdtType WHEN 'PT' THEN NRD.ResponseReportNumber END) AS PT_ContractorRTReportNumber,
                           Max(CASE NRD.NdtType WHEN 'PT' THEN NRD.Remark END) AS PT_RTSegment                 

                    FROM   NRD NRD
                           LEFT OUTER JOIN NdtReports NR
                                        ON NRD.ReportId = NR.Id
                    WHERE  NRD.JointId = c.Id
                           AND NRD.NdtType IN ( 'RT', 'PT', 'PWHT', 'MT', 'UT' )
                    ORDER  BY NRD.Id DESC) b

4 个答案:

答案 0 :(得分:1)

我猜您的查询可以像这样简化

SELECT *
FROM   joints c
       OUTER Apply (SELECT Max(CASE NdtType WHEN 'RT' THEN RequestNumber END) AS RT_MasterRTRequestNumber,
                           Max(CASE NdtType WHEN 'RT' THEN NdtReportNumber END) AS RT_ContractorRTRequestNumber,
                           Max(CASE NdtType WHEN 'RT' THEN ResponseReportDatetime END) AS RT_RTDate,
                           Max(CASE NdtType WHEN 'RT' THEN Defect END) AS RT_RTDefect,
                           Max(CASE NdtType WHEN 'RT' THEN ResponseReportNumber END) AS RT_ContractorRTReportNumber,
                           Max(CASE NdtType WHEN 'RT' THEN Remark END) AS RT_RTSegment,
                           Max(CASE NdtType WHEN 'PT' THEN RequestNumber END) AS PT_MasterRTRequestNumber,
                           Max(CASE NdtType WHEN 'PT' THEN NdtReportNumber END) AS PT_ContractorRTRequestNumber,
                           Max(CASE NdtType WHEN 'PT' THEN ResponseReportDatetime END) AS PT_RTDate,
                           Max(CASE NdtType WHEN 'PT' THEN Defect END) AS PT_RTDefect,
                           Max(CASE NdtType WHEN 'PT' THEN ResponseReportNumber END) AS PT_ContractorRTReportNumber,
                           Max(CASE NdtType WHEN 'PT' THEN Remark END) AS PT_RTSegment,
                           ....
                    FROM   (SELECT TOP 1 WITH ties NRD.NdtType,
                                                   NRD.RequestNumber,
                                                   NR.NdtReportNumber,
                                                   NRD.ResponseReportDatetime,
                                                   NRD.Defect,
                                                   NRD.ResponseReportNumber,
                                                   NRD.Remark
                            FROM   dbo.NdtReportDetails NRD
                                   LEFT OUTER JOIN NdtReports NR
                                                ON NRD.ReportId = NR.Id
                            WHERE  NRD.JointId = c.Id
                                   AND NRD.NdtType IN ( 'RT', 'PT', 'PWHT', 'MT', 'UT' )
                            ORDER  BY NdtReportDetails.Id DESC) i)b 

答案 1 :(得分:1)

尝试这样的事情......

WITH X AS (
SELECT C.*
     , RD.RequestNumber         AS MasterRTRequestNumber
     , R.NdtReportNumber        AS ContractorRTRequestNumber
     , RD.ResponseReportDatetime AS RTDate
     , RD.Defect                as RTDefect
     , RD.ResponseReportNumber  AS ContractorRTReportNumber
     , RD.Remark                as RTSegment
     ,ROW_NUMBER() OVER (PARTITION BY c.Id , RD.NdtType ORDER BY RD.Id DESC) rn 
FROM        dbo.NdtReportDetails RD
LEFT OUTER JOIN dbo.NdtReports   R ON RD.ReportId = R.Id 
LEFT OUTER JOIN dbo.joints       c ON RD.JointId=c.Id
where RD.NdtType IN ('RT','PT' , 'PWHT' , 'MT' ,'UT')
)
SELECT * 
FROM X 
WHERE rn = 1

答案 2 :(得分:0)

在where where条件的字段上创建一个字段索引,例如在JointId字段上:

CREATE INDEX ndx_NdtReportDetails_JId ON NdtReportDetails (JointId);
... more indexes here...

不要为固定值字段创建2个字段索引或索引(例如NdtType字段)

答案 3 :(得分:0)

你有没有链接“NdtReports”记录的任何“NdtReportDetails”记录? 它甚至可能吗?因此,不要在子查询中使用LEFT JOIN。使用INNER JOIN,我认为这会有所帮助。