我应该使用什么技术来优化SQL查询

时间:2015-07-03 06:44:25

标签: sql-server

您好我有一个存储过程,用于在搜索时获取记录。此过程返回数百万条记录。但是,在搜索过程中发现了一个错误,当某些条件满足时,它也会在某些情况下返回重复记录。我找到了它返回重复记录的错误:下面是有问题的查询:

With cteAutoApprove (AcctID, AutoApproved,DecisionDate)                
AS (
select 
    A.AcctID,
    CAST(autoEnter AS SMALLINT) AS AutoApproved, 
    DecisionDate 
from 
(
    SELECT 
        awt.AcctID, 
        MIN(awt.dtEnter) AS DecisionDate
    FROM
        dbo.AccountWorkflowTask awt 
        JOIN dbo.WorkflowTask wt ON awt.WorkflowTaskID = wt.WorkflowTaskID
        Join Task T on T.TaskID = wt.TaskID
    WHERE
        (
            (T.TaskStageID = 3 and awt.ReasonIDExit is NULL) 
            OR (wt.TaskID IN (9,15,201,208,220,308,319,320,408,420,508,608,620,1470,1608,1620))
        )
    GROUP BY 
        awt.AcctID
) A 
Join AccountWorkflowTask awt1 
    on awt1.dtEnter=A.DecisionDate and awt1.AcctID=a.AcctID
), 

由于awt1.dtEnter = A.DecisionDate上的条件,此CTE返回重复记录,某些帐户的dtEnter完全相同。这是它返回重复记录的原因。

我的问题是我应该用什么来阻止这种情况。我不能在这里使用Distinct,因为它肯定会减慢搜索过程。我应该使用Rank或Dense Rank以便优化它并且查询花费更少的时间来执行结果?还是其他一些技巧?请帮忙,因为我实际上被困在这里

1 个答案:

答案 0 :(得分:1)

看起来它确实是row_number的一个很好的候选者(不是排名,在相同的acctid上有相同的日期,你还有多个记录) 显然,我不能在这里测试查询,但是要对它进行测试:

select 
    A.AcctID,
    CAST(autoEnter AS SMALLINT) AS AutoApproved, 
    DecisionDate 
from 
(
    SELECT 
        awt.AcctID, 
        awt.dtEnter AS DecisionDate,
        autoEnter,
        row_number() over (partition by awt.acctid order by awt.dtEnter) rnr
    FROM
        dbo.AccountWorkflowTask awt 
        JOIN dbo.WorkflowTask wt ON awt.WorkflowTaskID = wt.WorkflowTaskID
        Join Task T on T.TaskID = wt.TaskID
    WHERE
        (
            (T.TaskStageID = 3 and awt.ReasonIDExit is NULL) 
            OR (wt.TaskID IN (9,15,201,208,220,308,319,320,408,420,508,608,620,1470,1608,1620))
        )
) A 
where rnr = 1

这样,不再需要group by:获取第一个日期由row_number完成。也不是第二个连接,子查询已经包含所有数据(并且优化器足够智能,不会对它不需要的行做任何事情)

PS。因为sql server窗口函数工作效率非常高,使用row_number而不是min() - join构造,即使没有双行,也很可能获得性能提升。