Как я могу объединить несколько операторов обновления в Oracle? - PullRequest
2 голосов
/ 06 февраля 2012

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

Я нашел информацию о подобных проблемах в MySql, которая была полезна, но я не смог реализовать то, что узнал, возможно, Oracle работает по-другому.

Среди вещей, которые я пробовал; пакетная вставка с помощью слияния, создание вторичной таблицы temp_table и работа без временных таблиц, но улучшения не произошло.

Будучи новичком в Oracle, вполне возможно, что я ошибаюсь.

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

UPDATE TEMP_TABLE TI SET T.ItemPrice_One =
        (
         SELECT ItemPrice
         FROM   Temp.View_Items V
         WHERE  V.Item_Name                    =          'Item_Name_One'
         AND    V.ID                           =          T.ID
         AND    V.Date                         =          T.Date
        );

UPDATE TEMP_TABLE TI SET T.ItemPrice_Two =
        (
         SELECT ItemPrice
         FROM   Temp.View_Items V
         WHERE  V.Item_Name                    =          'Item_Name_Two'
         AND    V.ID                           =          T.ID
         AND    V.Date                         =          T.Date
        );

UPDATE TEMP_TABLE TI SET T.ItemPrice_Three =
        (
         SELECT ItemPrice
         FROM   Temp.View_Items V
         WHERE  V.Item_Name                    =          'Item_Name_Three'
         AND    V.ID                           =          T.ID
         AND    V.Date                         =          T.Date
        );

Ответы [ 4 ]

2 голосов
/ 07 февраля 2012

То, что вы пытаетесь сделать, - это, по сути, операция поворота - превращение нескольких значений строки в несколько значений столбца в одной строке. Ниже приведен один метод, использующий общую технику в Oracle для выполнения сводных запросов (не проверено, но я думаю, что оно должно работать как есть). Начиная с версии 11g, есть встроенная операция PIVOT, но я пока еще не обращал на нее внимания - это может быть более прямой способ сделать то, что вам нужно.

UPDATE TEMP_TABLE TI SET ( T.ItemPrice_One, T.ItemPrice_Two,T.ItemPrice_Three )  =
    (
     SELECT
       MAX( CASE WHEN V.Item_Name='Item_Name_One' THEN ItemPrice ELSE NULL END ) Item_Price_One,
       MAX( CASE WHEN V.Item_Name='Item_Name_Two' THEN ItemPrice ELSE NULL END ) Item_Price_Two,
       MAX( CASE WHEN V.Item_Name='Item_Name_Three' THEN ItemPrice ELSE NULL END ) Item_Price_Three
     FROM   Temp.View_Items V
     WHERE  V.ID                           =          T.ID
     AND    V.Date                         =          T.Date
    );
1 голос
/ 06 февраля 2012

Может быть, вы можете попробовать изучить использование оператора MERGE. Это может позволить вам избежать трех сканирований таблицы просмотра. У меня нет экземпляра, с которым можно экспериментировать, но вот примерное предположение идеи:

MERGE INTO TEMP_TABLE t
   USING (SELECT Item_name, ItemPrice
            FROM Temp.View_Items V
            WHERE V.Item_Name IN ('Item_Name_One', 'Item_Name_Two', 'Item_Name_Three')
              AND V.ID = T.ID
              AND V.Date = T.Date) s
   ON (...join condition here... t.item_name = v.item_name??)
   WHEN MATCHED THEN
     UPDATE SET t.ItemPrice_One = DECODE(s.ItemPrice, 'Item_Name_One', v.ItemPrice, t.ItemPrice_One)
               ,t.ItemPrice_Two = DECODE(s.ItemPrice, 'Item_Name_Two', v.ItemPrice, t.ItemPrice_Two)
               ,t.ItemPrice_Three = DECODE(s.ItemPrice, 'Item_Name_Three', v.ItemPrice, t.ItemPrice_Three);
0 голосов
/ 07 февраля 2012

Слияние - лучшая ставка в этом сценарии.

0 голосов
/ 06 февраля 2012
UPDATE TEMP_TABLE TI SET T.ItemPrice_One =
        (
         SELECT ItemPrice
         FROM   Temp.View_Items V
         WHERE  V.Item_Name                    =          'Item_Name_One'
         AND    V.ID                           =          T.ID
         AND    V.Date                         =          T.Date
        )
,       T.ItemPrice_Two =
        (
         SELECT ItemPrice
         FROM   Temp.View_Items V
         WHERE  V.Item_Name                    =          'Item_Name_Two'
         AND    V.ID                           =          T.ID
         AND    V.Date                         =          T.Date
        )
,       T.ItemPrice_Three =
        (
         SELECT ItemPrice
         FROM   Temp.View_Items V
         WHERE  V.Item_Name                    =          'Item_Name_Three'
         AND    V.ID                           =          T.ID
         AND    V.Date                         =          T.Date
        );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...