2015-11-12 2 views
0

Мне любопытно, что лучше всего обновлять несколько строк в моей базе данных, если у меня есть список идентификаторов, предоставляемых внешней системой?Лучшая практика обновления нескольких строк на основе списка ключей

Простой UPDATE table SET y=z WHERE id IN (?); не так, поскольку мы можем получить больше, чем tousand ID, что является пределом Оракула.

Конечно, у нас есть некоторые идеи, такие как разделение на несколько запросов, с использованием временной таблицы и условий EXIST, но Id'like, чтобы увидеть лучшую практику и знать теорию.

EDIT: этот вопрос не является гонке за самый быстрый ответ, но о лучшей практике и ее теоретическом фоне. Идентификаторы предоставляются внешней системой! Никакой другой таблицы для соединения или другого выбора. По временной таблице я имел в виду глобальную временную таблицу (функцию оракула), не создавая anf, отбрасывая новую таблицу для каждого запроса! Пожалуйста, не отвечайте только потому, что хотите быть быстрыми, или если вы не понимаете.

+2

Возможный дубликат [Как разрешить ORA-01795 в Java-коде] (http://stackoverflow.com/q/26745971/266304). Массив позволит вашему обновлению стать 'UPDATE table SET y = z WHERE id IN (SELECT column_value FROM TABLE (?))'. –

+0

Как часто выполняется этот запрос? Некоторые типичные рекомендации могут не применяться, если этот запрос выполняется только несколько раз в день. –

+0

В любом случае, может не быть лучшей практики; существует несколько подходов, и они могут обмениваться простотой, легкостью кодирования/обслуживания, скоростью, нагрузкой ... Я бы использовал метод сбора массива/таблицы, но могут быть преимущества для других, которых у меня не было, или даже слышал о; и я не сравнивал варианты. Для меня это было более чем достаточно, но, возможно, это было неправильно. –

ответ

0

Можете ли вы использовать это?

UPDATE table 
SET a.column=b.column 
FROM table a 
JOIN your_id_table b ON a.id=b.id 

Как вы заполнения "(?)" В вашем предложении IN?

+0

В этом вопросе говорится, что это «список идентификаторов, предоставляемых внешней системой», а не из другой таблицы; поэтому 'your_id_table' не существует? Вы предлагаете временную таблицу, заполненную каким-то образом, или выражение коллекции таблиц, или предполагая, что существует реальная таблица для присоединения? –

+0

В качестве предлагаемой временной таблицы я имел в виду глобальную временную таблицу (функция Oracle). Я бы ввел идентификаторы, которые я хочу обновить, а затем перейдите к обновлению, используя условие WHERE EXISTS. – Kousalik

+0

Алекс, я попросил ясности, как он заполняет пробел в своем разделе IN, потому что это будет указывать на то, как он в настоящее время хранит данные. Это может быть таблица, временная таблица или постоянная таблица, как описывает Kousalik. –

0

Вы, вероятно, есть список в другой таблице так

UPDATE table 
SET y=z 
WHERE id IN (SELECT ID 
      FROM YourOtherTable); 

Также можно использовать exists

UPDATE table T1 
SET y=z 
WHERE Exists (SELECT ID 
       FROM YourOtherTable T2 
       WHERE T2.ID = T1.ID); 
+0

Нет, у меня нет списка в другой таблице. – Kousalik

+0

Будьте осторожны с использованием IN (подзапроса), поскольку это убийца производительности. Подзапрос должен быть полностью оценен, что может занять некоторое время. EXISTS альтернатива в таком случае лучше и обычно быстрее, а также вариант, который я буду использовать вместе с временной таблицей для хранения идентификаторов. – Kousalik

0

Edit: я предположил, что вы используете Java, чтобы сделать ваши обновления.

Разве не требуется больше времени для создания временной таблицы, заполнить ее идентификаторами, а затем выполнить против нее? (Или, может быть, я неправильно понимаю сценарий).

Что бы сделать, это разделить большой список идентификаторов на разделы, а затем использовать исполнителя представить партии к моему DB слоя, например:

  ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10); 
      List<Integer> aLotOfIds = new ArrayList<Integer>(); // imagine heaps of IDS 
      List<List<Integer>> partition = Lists.partition(aLotOfIds, 1000); 
      partition.forEach(p -> { 
       newFixedThreadPool.submit(() -> { 
        // execute update for a batch 
       }); 
      }); 
+0

Глобальная временная таблица - это функция Oracle. Это не означает, что вы создаете и отбрасываете таблицу каждый раз, когда выполняется запрос. – Kousalik

Смежные вопросы