Sql server 需要帮助来优化此查询吗

Sql server 需要帮助来优化此查询吗,sql-server,tsql,sql-server-2000,Sql Server,Tsql,Sql Server 2000,你能帮我优化我的这个查询吗?我已经没有办法优化这个了。这里的数据检索时间是6分钟,我想减少它。希望你能帮助我 -- Main query DECLARE @ProdClass VARCHAR(10) ,@ModelID VARCHAR(10) ,@ServiceStartDate DATETIME ,@ServiceEndDate DATETIME ,@SvcID VARCHAR(10) ,@StateID VARCHAR(10) ,@AreaID VARCHAR(10) SET @Prod

你能帮我优化我的这个查询吗?我已经没有办法优化这个了。这里的数据检索时间是6分钟,我想减少它。希望你能帮助我

-- Main query
DECLARE @ProdClass VARCHAR(10)
,@ModelID VARCHAR(10)
,@ServiceStartDate DATETIME
,@ServiceEndDate DATETIME
,@SvcID VARCHAR(10)
,@StateID VARCHAR(10)
,@AreaID VARCHAR(10)

 SET @ProdClass = 'WPS'
 SET @ModelID = 'BM'
 SET @ServiceStartDate = convert(datetime, '10/1/2007')
 SET @ServiceEndDate = CONVERT(DATETIME, '11/1/2007')
 SET @SvcID = '358'
 SET @StateID = 'JB'
 SET @AreaID = ''

SELECT DISTINCT cus.MCUS_CUSID
    ,cus.MCUS_ENAME
    ,mod.MMOD_ENAME
    ,rou.MROU_SERNO
    ,svc.MSVC_SVCID AS SVC_NAME
    ,ar.MARE_ENAME
    ,dbo.ufn_GetLastXApptDate(rou.MROU_ROUID) AS MROU_APTDT
    ,rou.MROU_LSVDT
    ,(
        CASE MROU_FRSVE
        WHEN 'Y'
            THEN 'FREE'
        WHEN 'N'
            THEN 'NORMAL'
        END
    ) AS SERVICE_DUE_TYPE
FROM dbo.MROU_FIL AS rou
INNER JOIN dbo.MCUS_FIL AS cus ON rou.MROU_CUSID = cus.MCUS_CUSID
INNER JOIN dbo.MMOD_FIL AS mod ON rou.MROU_MODID = mod.MMOD_MODID
INNER JOIN dbo.MSVC_FIL AS svc ON rou.MROU_SVCID = svc.MSVC_SVCID
INNER JOIN dbo.MADR_FIL AS adr ON cus.MCUS_CUSID = adr.MADR_CUSID
INNER JOIN dbo.MSTA_FIL AS st ON adr.MADR_STAID = st.MSTA_STAID
INNER JOIN dbo.MARE_FIL AS ar ON adr.MADR_AREID = ar.MARE_AREID
INNER JOIN dbo.FAPT_FIL AS apt ON rou.MROU_ROUID = apt.FAPT_ROUID
WHERE rou.MROU_STAT = 'ACTIVE'
AND rou.MROU_CUSPF = 'MY'
AND apt.FAPT_APTTY in ('mf','m1','m2','m3','m4','m5','m6', 'mm')
AND ((@ProdClass = '') OR (@ProdClass <> '' AND rou.MROU_CLSID = @ProdClass))
AND ((@ModelID = '') OR (@ModelID <> '' AND rou.MROU_MODID = @ModelID))
AND (
    ((@ServiceStartDate = '') OR (@ServiceStartDate <> '' AND rou.MROU_LSVDT >= @ServiceStartDate))
    AND
    ((@ServiceEndDate = '') OR (@ServiceEndDate <> '' AND rou.MROU_LSVDT <= @ServiceEndDate))
)
AND ((@SvcID = '') OR (@SvcID <> '' AND svc.MSVC_SVCID = @SvcID))
AND ((@StateID = '') OR (@StateID <> '' AND adr.MADR_STAID = @StateID))
AND ((@AreaID = '') OR (@AreaID <> '' AND adr.MADR_AREID = @AreaID))
ORDER BY rou.MROU_LSVDT


-- function -- 
ALTER FUNCTION [dbo].[ufn_GetLastXApptDate] 
(
@rouid numeric(18,0)
)
RETURNS datetime
AS
BEGIN
    DECLARE @ApptDate datetime

    SELECT @ApptDate = MAX(FAPT_APTDT)
    FROM dbo.FAPT_FIL
    WHERE FAPT_ROUID = @rouid
        AND FAPT_STAT= 'X'
        AND FAPT_APTTY in ('mf','m1','m2','m3','m4','m5','m6', 'mm')

    RETURN @ApptDate

END

SQL Server必须为每一行调用标量函数。要让它自由地以基于集合的操作方式执行函数的查询,请将函数内联移动。更改:

,dbo.ufn_GetLastXApptDate(rou.MROU_ROUID) AS MROU_APTDT
致:

您的查询看起来也像一个搜索查询,对于不同的参数值,它可能受益于不同版本的执行计划。通过添加以下内容,可以强制每次执行新的查询计划:

option  (recompile)

在查询结束时。

SQL Server必须为每一行调用标量函数。要让它自由地以基于集合的操作方式执行函数的查询,请将函数内联移动。更改:

,dbo.ufn_GetLastXApptDate(rou.MROU_ROUID) AS MROU_APTDT
致:

您的查询看起来也像一个搜索查询,对于不同的参数值,它可能受益于不同版本的执行计划。通过添加以下内容,可以强制每次执行新的查询计划:

option  (recompile)

在查询结束时。

尝试创建索引,索引键上的所有列按照它们在每个表的查询中出现的顺序执行联接。

尝试创建索引,索引键上的所有列按照它们在每个表的查询中出现的顺序执行联接。

您有哪些索引在桌子上?如果没有,就从那里开始。实际上很多。我不知道从哪里开始。在执行连接的每个键上至少应该有索引——除非表非常小。表上有什么索引?如果没有,就从那里开始。实际上很多。我不知道从何处开始。在执行联接的每个键上都应该至少有索引,除非表非常小。如果要将此代码保留在函数中,请将其转换为返回:rouid,LastXApptDate的表函数。您不会得到与此答案相同的性能提升,但您仍然可以重用代码。@Jeff:An将与内联代码一样高效。明白了。非常感谢!我不知道函数的调用总是会影响查询的性能。如果要在函数中保留这段代码,请将其转换为返回rouid、LastXApptDate的表函数。您不会得到与此答案相同的性能提升,但您仍然可以重用代码。@Jeff:An将与内联代码一样高效。明白了。非常感谢!我不知道调用函数总是会影响查询的性能。