Пришвидшення видалення запису с таблиці CARD, підвищення продуктивності ХП UPDATE_NAKL_TOTAL_VALS

Обговорення питань, пов'язаних з функціонуванням програми
Відповісти
ITkachuk
Повідомлень: 18
З нами з: 11 липня 2017, 17:47

Пришвидшення видалення запису с таблиці CARD, підвищення продуктивності ХП UPDATE_NAKL_TOTAL_VALS

Повідомлення ITkachuk » 15 березня 2021, 21:43

Доброго вечора!

Провожу процедуру архівування документів
В таблиці CARD 487430 записів.
Индекс на полі CARD присутній с доброю селективністю
| Показать
Screenshot_1.png
Screenshot_1.png (26.04 Кіб) Переглянуто 813 разів
Однак процедура видалення запису з таблиці займає в середньому 7 сек.
| Показать
Screenshot_3.png
Screenshot_3.png (12.7 Кіб) Переглянуто 813 разів
Щодто тригерів - тут також на кожній задіяній таблиці присутній індекс.
| Показать
Screenshot_2.png
Screenshot_2.png (51.61 Кіб) Переглянуто 813 разів
Є в когось якісь ідеї, чому так може відбуватися и як можна цьому зарадити?

Завчасно вдячний за будь-яку підказку

P.S.: Подібна біда і з хранимкою UPDATE_NAKL_TOTAL_VALS(?,?)
| Показать

Код: Виділити все

begin  
    if (ispn = 1) then
    begin
        for select TAB1_A131, TAB1_A133 from fj1201002_tab1 where cardcode = :card_code into
            :UKTVAL, :SERVICEVAL
        do
        begin
            if(CHAR_LENGTH(UKTVAL) > 0) then
                UKTCNT = UKTCNT + 1;
            if(CHAR_LENGTH(SERVICEVAL) > 0) then
                SERVICECNT = SERVICECNT + 1;
            ROWCNT = ROWCNT + 1;
        end
        
        update FJ1201002_MAIN FJ set
            UKTPRESENCE = case
                when :UKTCNT = 0
                then 'Відсутній'
                when :ROWCNT > :UKTCNT
                then 'Наявний частково'
                else 'Наявний' end,
            SERVICEPRESENCE = case
                when :SERVICECNT = 0
                then 'Відсутній'
                when :ROWCNT > :SERVICECNT
                then 'Наявний частково'
                else 'Наявний' end,
            N2_1 = CASE WHEN COALESCE(FJ.N2_12, 0) <> 0 OR COALESCE(FJ.N2_13, '') <> '' THEN
                COALESCE(FJ.N2_11, '') || '/' || COALESCE(CAST(FJ.N2_12 AS VARCHAR(30)), '') || '/' || COALESCE(FJ.N2_13, '')
                ELSE FJ.N2_11 END
            WHERE cardcode = :card_code;
    end
    else
    begin
        for select TAB1_A31, TAB1_A33 from fj1201202_tab1 where cardcode = :card_code into
            :UKTVAL, :SERVICEVAL
        do
        begin
            if(CHAR_LENGTH(UKTVAL) > 0) then
                UKTCNT = UKTCNT + 1;
            if(CHAR_LENGTH(SERVICEVAL) > 0) then
                SERVICECNT = SERVICECNT + 1;
            ROWCNT = ROWCNT + 1;
        end
        
        update FJ1201202_MAIN FJ set
            UKTPRESENCE = case
                when :UKTCNT = 0
                then 'Відсутній'
                when :ROWCNT > :UKTCNT
                then 'Наявний частково'
                else 'Наявний' end,
            SERVICEPRESENCE = case
                when :SERVICECNT = 0
                then 'Відсутній'
                when :ROWCNT > :SERVICECNT
                then 'Наявний частково'
                else 'Наявний' end,
            CORRCMPL = ( CASE WHEN FJ.N2 IS NULL AND
                FJ.N2_1 IS NULL AND
                ( SELECT FIRST 1 TAB1.TAB1_A21 FROM FJ1201202_TAB1 TAB1 WHERE TAB1.CARDCODE = FJ.CARDCODE ) IS NULL
                   THEN NULL
                   ELSE LPAD( CAST( EXTRACT ( DAY FROM FJ.N2 ) AS VARCHAR(2) ), 2, '0' ) || '.' || LPAD( CAST( EXTRACT( MONTH FROM FJ.N2 ) AS VARCHAR(2)), 2, '0' ) || '.' || EXTRACT( YEAR FROM FJ.N2 ) ||
                    '/' ||
                    FJ.N2_1 ||
                    '/' ||
                    ( SELECT FIRST 1 TAB1.TAB1_A21 FROM FJ1201202_TAB1 TAB1 WHERE TAB1.CARDCODE = FJ.CARDCODE ) END ),
                N2_1 = CASE WHEN COALESCE(FJ.N2_12, 0) <> 0 OR COALESCE(FJ.N2_13, '') <> '' THEN
                        COALESCE(FJ.N2_11, '') || '/' || COALESCE(CAST(FJ.N2_12 AS VARCHAR(30)), '') || '/' || COALESCE(FJ.N2_13, '')
                        ELSE FJ.N2_11 END,
                N1 = CASE WHEN COALESCE(FJ.N1_12, 0) <> 0 OR COALESCE(FJ.N1_13, '') <> '' THEN
                        COALESCE(FJ.N1_11, '') || '/' || COALESCE(CAST(FJ.N1_12 AS VARCHAR(30)), '') || '/' || COALESCE(FJ.N1_13, '')
                        ELSE FJ.N1_11 END
            WHERE cardcode = :card_code;
    end
end
Індекс на поле cardcode присутній для відповідних таблиць, але виконання процедури займає порядка 8 сек.
Відповідно імпорт однієї НН замає неприпустимо багато часу при відносно великому обсязі таких документів, що потрібно імортувати у відносно короткий проміжок часу. Це й спонукало мене на архівування документів, але й тут я зіткнувся с проблемою продуктивності

Інформація про систему
| Показать
Server Version: WI-V2.1.4.18393 Firebird 2.1
Server Implementation: Firebird/x86/Windows NT
Service Version: 2

OS Name Microsoft Windows Server 2008 R2 Standard
Version 6.1.7601 Service Pack 1 Build 7601
Installed Physical Memory (RAM) 6,00 GB

Все на SSD

hatmaster
Повідомлень: 595
З нами з: 21 вересня 2016, 12:52

Re: Пришвидшення видалення запису с таблиці CARD, підвищення продуктивності ХП UPDATE_NAKL_TOTAL_VALS

Повідомлення hatmaster » 16 березня 2021, 12:11

Єдина рекомендація з досвіду - робити ці процедури на локальній машині в локальній версії, потім підкидати бази на сервер
Все пройдет, и это тоже. Реально лишь одно - мир иллюзорен! Все остальное фантастика ...

Відповісти

Повернутись до “Помилки у роботі програми”