执行时间过长时的SQL情况

执行时间过长时的SQL情况,sql,sql-server,Sql,Sql Server,我需要在我的病例陈述中找到最近的creationdate中尉。现在,它工作正常,但执行几乎需要2分钟。 然而,如果我把 and lt.CREATIONDATE = (SELECT MAX(lt.creationdate) FROM dbo.LOANTRACKING lt WHERE lt.PARENTACCOUNT = l.PARENTACCOUNT AND lt.type = 54) where子句中的代码,它提供了不正确的数据 我的问题是: DECLARE

我需要在我的病例陈述中找到最近的creationdate中尉。现在,它工作正常,但执行几乎需要2分钟。 然而,如果我把

and lt.CREATIONDATE = (SELECT MAX(lt.creationdate)
    FROM dbo.LOANTRACKING lt
    WHERE lt.PARENTACCOUNT = l.PARENTACCOUNT
        AND lt.type = 54)
where子句中的代码,它提供了不正确的数据

我的问题是:

DECLARE @StartDate AS SMALLDATETIME
DECLARE @EndDate AS SMALLDATETIME
DECLARE @UserName AS VARCHAR(50)

SET @StartDate = '2019-11-01'
SET @EndDate = '2019-11-30'
SET @UserName = 'YEN NGUYEN'

SELECT q.[User ID]
    , q.[User Name]
    , COUNT(q.Loans) OVER (PARTITION BY q.[User ID], q.[Loan Description]) AS [Loans]
    , q.[Loans] AS [Account Number]
    , q.[Loan Description]
    , q.LoanBalance AS [Loan Balance]
    , q.[Loan ID] AS [Loan ID]
    , COUNT(q.[Debt Protection]) AS [Debt Protection]
FROM(
SELECT DISTINCT
    l.USERCHAR2 AS [User ID]
    , ucat.UserName AS [User Name]
    , l.PARENTACCOUNT AS [Loans]
    , l.balance AS [LoanBalance]
    , l.ID AS [Loan ID]
    , CASE WHEN (l.type >= 1 AND l.type <= 299)
        THEN 'Auto Loans'
        WHEN (l.type >= 300 AND l.type <= 449)
        THEN 'Personal Loans'
        WHEN (l.type >= 450 AND l.TYPE <= 465)
        THEN 'Credit Card Loans'
        WHEN ((l.type >= 500 AND l.TYPE <= 510)
            OR (l.type >= 700 AND l.type <= 710))
        THEN 'Lines of Credit'
    END AS [Loan Description]
    , CASE WHEN lt.userdate1 IS NOT NULL
        AND ((l.type >= 1 AND l.type <= 299)
        OR (l.type >= 300 AND l.type <= 449))
    AND (lt.CREATIONDATE >= @StartDate AND lt.CREATIONDATE <= @EndDate)
    AND lt.type = 54
    AND lt.ProcessDate = CONVERT(VARCHAR(8), dateadd(day,-1, getdate()), 112)
    and lt.CREATIONDATE = (SELECT MAX(lt.creationdate)
        FROM dbo.LOANTRACKING lt
        WHERE lt.PARENTACCOUNT = l.PARENTACCOUNT
            AND lt.type = 54)
    THEN lt.PARENTACCOUNT
    END AS [Debt Protection]
from dbo.LOAN l
inner join arcu.ARCUUserCategory UCat
    ON UCat.UserNumber = l.USERCHAR2
JOIN dbo.LOANTRACKING lt
    ON l.PARENTACCOUNT = lt.PARENTACCOUNT
where l.CLOSEDATE is null 
    AND (l.OPENDATE >= @StartDate AND l.OPENDATE <= @EndDate)
    AND l.ProcessDate = CONVERT(VARCHAR(8), dateadd(day,-1, getdate()), 112)
    AND UCat.UserName IN (@UserName)
) q
GROUP BY q.[User ID]
    , q.LoanBalance
    , q.Loans
    , q.[Loan Description]
    , q.[User Name]
    , q.[Loan ID]
ORDER BY q.[User ID], q.[User Name], q.[Loan Description]
将@StartDate声明为SMALLDATETIME
将@EndDate声明为SMALLDATETIME
将@UserName声明为VARCHAR(50)
设置@StartDate='2019-11-01'
设置@EndDate='2019-11-30'
SET@UserName='YEN-NGUYEN'
选择q.[用户ID]
,q.[用户名]
,将(q.Loans)除以(按q.[用户ID],q.[贷款说明]划分)计为[贷款]
,q.[贷款]作为[账号]
,q.[贷款说明]
,q.贷款余额为[贷款余额]
,q.[贷款ID]作为[贷款ID]
,将(q[债务保护])算作[债务保护]
从(
选择不同的
l、 USERCHAR2作为[用户ID]
,ucat.UserName为[用户名]
,l.PARENTACCOUNT AS[贷款]
,l.余额为[贷款余额]
,l.ID为[贷款ID]

,当(l.type>=1和l.type=300和l.type=450和l.type=500和l.type=700和l.type=1和l.type=300和l.type=@StartDate和lt.CREATIONDATE=@StartDate和l.OPENDATE时,我建议尝试连接到类似的非相关子查询

...
JOIN (SELECT lt.PARENTACCOUNT, MAX(lt.creationdate) AS lastCDate
      FROM dbo.LOANTRACKING lt
      WHERE lt.type = 54
      GROUP BY lt.PARENTACCOUNT
) AS ltlastdates ON l.PARENTACCOUNT = ltlastdates.PARENTACCOUNT
...
然后,您应该能够在
案例中使用
ltlastdates.lastCDate


此外,如果还没有,则在
LOANTRACKING(PARENTACCOUNT,type,creationdate)
上创建一个复合索引可能会有很大帮助。

什么版本的查询提供了正确的数据?已经存在的代码提供了正确的数据,只需2分钟即可执行。哦,我明白了,我读过了“在where子句中”位,一个错误的想法是原始的没有子查询开始。