Надлежащий способ объявить курсор для огромного количества обновлений

Мне нужны некоторые предложения относительно того, ли моя идея в порядке или нет. У меня есть ситуация где:

Я должен сделать обновления каждой строки таблицы. Существует некоторая логика, вовлеченная в updation. Логика очень проста, но она должна быть сделана для каждой строки. Существует возможность каждой обновляемой строки.

В настоящее время я думаю о записи программы ESQL/C делать это. Я думаю о загрузке каждой строки в ее эквивалентную структуру C через выбор для курсора обновления, выполните логику и фиксацию. Какая роль делает ключевое слово ХРАНЕНИЯ, делают на курсоре? Я - бит, перепутанный ролью этого.

Эти обновления будут сделаны в течение системного периода времени простоя. Таблица содержит приблизительно 130 миллионов строк. Это имеет приблизительно 45 столбцов. Большинство столбцов имеет тип SMALLINT и ЦЕЛОЕ ЧИСЛО.

Я на правильном пути? Приветствующиеся предложения.

Базой данных будет Informix (версия 11.50 FC6 IDS)

1
задан kiamlaluno 17 January 2013 в 20:13
поделиться

2 ответа

Ключом к выполнению этой работы является выполнение работы на сервере, вместо того, чтобы заставлять сервер выбирать каждую строку, передавать ее клиенту, а затем принять данные обратно от клиента.

UPDATE YourTable
   SET y = (CASE WHEN z > x THEN p ELSE y)
 WHERE key_column BETWEEN lo_val AND hi_val;

Сложной частью, вероятно, будет разделение работы на управляемые суб-транзакции; вот в чем суть условия "lo_val .. hi_val".Если ваши логические журналы достаточно велики, чтобы обрабатывать все 130 миллионов обновляемых строк [примерно (2 * (размер строки + X) * количество строк), где X имеет значение около 20, я полагаю] с свободным пространством, тогда вы может сделать все сразу. Ясно, что это «обновляет» каждую строку.

Если вы решили, что должны сделать это в клиенте (ошибка, но ...), тогда:

Вы используете курсор SELECT с HOLD, чтобы он оставался открытым и правильно позиционировался между транзакциями. Вы запускаете транзакцию, выбираете несколько тысяч строк, обновляя каждую по мере необходимости. Убедитесь, что вы используете подготовленный оператор UPDATE; возможно, вы используете условие WHERE CURRENT OF.


Предлагаете ли вы поместить обновление как часть курсора в хранимой процедуре?

Нет, хотя вы можете сделать это в хранимой процедуре. Отчасти это зависит от того, собираетесь ли вы этим заниматься на регулярной основе; если да, то, возможно, хранимая процедура - хорошая идея, но я бы не стал делать это разовое упражнение.

Это зависит от того, как вы собираетесь определять lo_val и hi_val. Я бы, вероятно, использовал I4GL (потому что я свободно владею им), а затем я ожидал бы подготовить оператор UPDATE (с вопросительными знаками вместо 'lo_val' и 'hi_val'), а затем я ожидал бы выполнить это несколько раз, каждый раз формируя транзакцию с одним оператором. Итак, если вы решили использовать диапазоны lo_val..hi_val от 000000..099999, 100000..199999, ... тогда вы должны повторить:

for i = 0 to 10000000 step 100000
    let j = i + 99999
    execute p_update using i, j
end for

В I4GL вам не обязательно использовать подготовленный оператор . Если у вас IDS 11, вы можете составлять отчеты на SPL.В более ранних версиях и без особого снижения производительности (я сомневаюсь, что вы могли бы надежно ее измерить) вы могли бы просто использовать:

CREATE PROCEDURE update_your_table()
    DEFINE lo_val, hi_val INTEGER;

    FOR lo_val = 0 TO 1000000 STEP 100000
        LET hi_val = lo_val + 99999;
        UPDATE YourTable
           SET y = (CASE WHEN z > x THEN p ELSE y)
         WHERE key_column BETWEEN lo_val AND hi_val;
    END FOR;

END PROCEDURE;

Непроверенный код - используйте на свой страх и риск!

2
ответ дан 3 September 2019 в 01:11
поделиться

SPL - это правильный выбор! .. но я предлагаю вам сначала скопировать таблицу и протестировать массовое обновление.

0
ответ дан 3 September 2019 в 01:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: