花费太长时间执行的SQL情况

时间:2019-12-03 17:37:07

标签: sql sql-server

我需要在我的case语句中获取最新的lt.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]

我是否还有另一种方法可以获取case语句中的最新lt.creationdate?

这是我的结果:

enter image description here

1 个答案:

答案 0 :(得分:1)

建议不要尝试使用JOIN到类似的不相关子查询。

...
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中使用CASE

此外,如果还没有索引,那么LOANTRACKING(PARENTACCOUNT, type, creationdate)上的复合索引可能会有所帮助。