Курсор SQL Server очень медленно обновляется для каждой строки с хранимой процедурой внутри

#sql #performance #tsql #sql-server-2014 #database-cursor

#sql #Производительность #tsql #sql-server-2014 #база данных-курсор

Вопрос:

У меня проблема, при обновлении 50 тысяч записей требуется 30-45 минут для завершения. Но когда я обновляю 10k записей, это занимает всего 2-3 минуты.

Как я могу устранить эту проблему? Есть ли способ улучшить его выполнение без изменения Exec ICS_GetPrincipalInterest ?

Вот мой SQL-код, я уже пробовал использовать while инструкции, но это намного медленнее.

 CREATE TABLE #getPI
(
    BranchCodeValue VARCHAR(10), 
    AccountNumberValue VARCHAR(50), 
    PrincipalReturnValue MONEY,
    InterestReturnValue MONEY, 
    ServiceFeeReturnValue MONEY, 
    PCLIReturnValue MONEY, 
    PDInterestReturnValue MONEY, 
    PDPenaltyReturnValue MONEY, 
    MRIReturnValue MONEY, 
    DSTReturnValue MONEY, 
    DefInterestReturnValue MONEY, 
    OtherChargesReturnValue MONEY, 
    ODROCRReturnValue MONEY 
) 


SELECT TOP (50000) 
    BranchCode, AccountNumber 
INTO 
    #tempLoans 
FROM
    Loans801.dbo.LoanAccount 
WHERE
    (LoanStatus NOT LIKE '%clos%' 
     AND LoanStatus NOT LIKE '%write%') 
ORDER BY 
    dategranted DESC

DECLARE @getBR VARCHAR(50) 
DECLARE @getACCNT VARCHAR(100) 
DECLARE @setCutOffDate VARCHAR(10) = CONVERT(VARCHAR(10), GETDATE(), 101) 

DECLARE @MyCursor CURSOR; 

BEGIN 
    SET @MyCursor = CURSOR FOR 
        SELECT Branchcode, accountnumber 
        FROM #tempLoans       

    OPEN @MyCursor 

    FETCH NEXT FROM @MyCursor INTO @getBR, @getACCNT 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
        INSERT INTO #getPI 
            EXEC ICS_GetPrincipalInterest @getBR, @getACCNT, @setCutOffDate 

        FETCH NEXT FROM @MyCursor INTO @getBR, @getACCNT 
    END; 

    CLOSE @MyCursor; 
    DEALLOCATE @MyCursor; 
END; 

DROP TABLE #tempLoans 

SELECT * FROM #getPI 

DROP TABLE #getPI
  

Заранее спасибо! Пожалуйста, помогите мне 🙂

Комментарии:

1. Какая версия SQL?

2. @Shawn, Microsoft SQL Server 2014 — 12.0.2269.0 (X64) сэр

3. И что ICS_GetPrincipalInterest делает? Чаще всего курсор — не самый эффективный способ получить нужные данные. И каковы возможные значения, которые могут быть в LoanStatus ? Вам нужно использовать LIKE для получения этих значений, или существует множество общих значений? Но самый большой вопрос на самом деле касается sproc. Скорее всего, это можно сделать без курсора.

4. @Shawn, он вычисляет ежедневные проценты, платежи и многое другое для каждой записи, loanstatus имеет по крайней мере 5 типов статуса.

5. Верно, но могут ли вычисления выполняться непосредственно в запросе к данным? Нужен ли sproc? Возможно, потребуется переработать. Я предполагаю, что медлительность, которую вы видите, будет связана как с тем фактом, что вы используете курсор для выполнения некоторых вычислений на основе строк, так и с чем-то внутри курсора, который работает неэффективно. Кроме того, если у вас более 50 ТЫСЯЧ записей, содержащих всего около 5 LoanStaus значений, то вам, вероятно, следует нормализовать этот столбец и добавить к нему хороший индекс. Один только индекс, вероятно, значительно ускорил бы это.