Sybase: хранимая процедура вызывается из другой хранимой процедуры слишком медленно - PullRequest
0 голосов
/ 16 января 2019

Я пишу хранимую процедуру для базы данных Sybase. Я использую Sybase Central 16.0 в качестве среды разработки. Машина, на которой я работаю, работает под управлением Microsoft Windows Server 2012 R2 Standard и имеет 16 ГБ ОЗУ на процессоре 2,8 ГГц.

Моя хранимая процедура использует курсор для перебора записей в таблице с примерно 400 000 записей. Каждая запись записывается пошагово в переменную LONG VARCHAR, и каждая N-я запись proc запускает хеш-значение MD5 для переменной и сохраняет значение в отдельной таблице.

TABLE_NAME, DATE_TIME_RAN, FROM_RECORD, TO_RECORD, HASH_VALUE

Если я запускаю только хранимую процедуру для хеширования этой таблицы как блока SQL в SQL Anywhere (например, BEGIN ... <hash the table here> ... END;), она проходит через все записи и успешно завершается в течение двух минут. Однако, если я запускаю эту хранимую процедуру как встроенную команду в другой хранимой процедуре (например, CALL <MY_SCHEMA>.<MY_STORED_PROCEDURE>), она никогда не завершается.

Почему выполнение хранимой процедуры (в том же наборе данных) из другой хранимой процедуры выполняется по-другому?

1 Ответ

0 голосов
/ 31 января 2019

Удалось найти гораздо лучшее решение проблемы, не пробираясь по столу.Я подумал, что опубликую решение здесь для тех, кто может столкнуться с подобной проблемой.

Требование к хранимой процедуре состояло в том, чтобы проходить по большой таблице по одной строке за раз, объединяя содержимое каждого столбца встрока в строку и присвоение этого переменной.Каждые N строк этой переменной будут записаны в отдельную таблицу.Раньше я использовал курсор для этого, но разработчик в нашей команде обнаружил гораздо более быстрый способ использования предложения WITH.

INSERT INTO <MY_SCHEMA>.<MY_TABLE_THAT_WILL_CONTAIN_THE_CONCATENATED_VALUES_OF_EVERY_N_ROWS>
WITH 
    CONCATENATE_ROWS AS (
            SELECT RANK() OVER (ORDER BY <PRIMARY_KEY_COLUMN>) AS ROWID, <PRIMARY_KEY_COLUMN>, <COLUMN_1> || '' || <COLUMN_2> || '' || ... <COLUMN_N> AS ROW_DETAIL
            FROM <MY_TABLE_THAT_I_AM_QUERYING> 
            ORDER BY <PRIMARY_KEY_COLUMN>
    ), 
    GROUPED_ROWS AS (
            SELECT (((CONCATENATE_ROWS.ROWID-1)/ <number of rows I want to concatenate, e.g.: 10>)+1) AS GROUPID, CAST(LIST(CONCATENATE_ROWS.ROW_DETAIL, '' ORDER BY <PRIMARY_KEY_COLUMN>) AS VARCHAR(4000)) AS CONCAT_DETAILS
             FROM CONCATENATE_ROWS 
             GROUP BY (((CONCAT_ORDERS.ROWID-1)/ <number of rows I want to concatenate, e.g.: 10>)+1)
    )
SELECT <Whatever columns I want to insert into <MY_TABLE_THAT_WILL_CONTAIN_THE_CONCATENATED_VALUES_OF_EVERY_N_ROWS>> 
FROM GROUPED_ROWS;
...