Вставить не удалось, затем обновить ИЛИ Загрузить, а затем решить, если вставить или обновить - PullRequest
0 голосов
/ 19 декабря 2008

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

Какой подход является лучшим для достижения лучших результатов производительности:

  1. Перебрать список (список объектов, с таблицей pk), попытаться вставить запись в базу данных. Если вставка не удалась, запустите обновление

  2. Попробуйте загрузить запись из базы данных. если результаты поиска обновляются, если нет, вставьте запись.

  3. другой вариант? расскажи мне об этом:)

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

Я говорю о таблице БД, которая может содержать более 100 миллионов записей в зрелой форме.

Каким будет ваш подход? Производительность - моя самая важная цель.

Ответы [ 5 ]

4 голосов
/ 19 декабря 2008

Если ваша база данных поддерживает MERGE, я бы подумал, что она наиболее эффективна (и обрабатывает все данные как один набор).

См:

http://www.oracle.com/technology/products/oracle9i/daily/Aug24.html

https://web.archive.org/web/1/http://blogs.techrepublic%2ecom%2ecom/datacenter/?p=194

1 голос
/ 21 декабря 2008

Вариант 2 не будет самым эффективным. База данных уже будет выполнять эту проверку для вас, когда вы будете выполнять фактическую вставку или обновление для обеспечения применения первичного ключа. Выполнив эту проверку самостоятельно, вы дважды понесете издержки при поиске в таблице, а также получите дополнительную информацию из вашего Java-кода. Выберите, какой случай является наиболее вероятным, и используйте оптимистичный код.

Расширяя опцию 1, вы можете использовать хранимую процедуру для обработки вставки / обновления. В этом примере с синтаксисом PostgreSQL предполагается, что вставка является нормальным случаем.

CREATE FUNCTION insert_or_update(_id INTEGER, _col1 INTEGER) RETURNS void
AS $$
    BEGIN
        INSERT INTO
            my_table (id, col1)
        SELECT
            _id, _col1;
    EXCEPTION WHEN unique_violation THEN
        UPDATE
            my_table
        SET
            col1 = _col1
        WHERE
            id = _id;
    END;
END;
$$
LANGUAGE plpgsql;

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

Как упоминалось в некоторых других ответах, наиболее эффективный способ выполнить эту операцию - один пакет:

  1. Возьмите все строки, переданные веб-службе, и массово вставьте их во временную таблицу
  2. Обновление строк в основной таблице из временной таблицы
  3. Вставка новых строк в основную таблицу из временной таблицы
  4. Утилизировать временную таблицу

Тип используемой временной таблицы и наиболее эффективный способ управления ею будет зависеть от используемой вами базы данных.

1 голос
/ 19 декабря 2008

MySQL поддерживает это:

INSERT INTO foo
SET bar='baz', howmanybars=1
ON DUPLICATE KEY UPDATE howmanybars=howmanybars+1
1 голос
/ 19 декабря 2008

Важно понять баланс или соотношение между количеством вставок и количеством обновлений в списке, который вы получаете. ИМХО, вы должны реализовать абстрактную стратегию, которая гласит «сохраняет это в базе данных». Затем создайте конкретные стратегии, которые (например):

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

А затем извлеките стратегию для использования (например, полное имя класса) из файла конфигурации. Таким образом, вы можете легко переключаться с одной стратегии на другую. Если это возможно, может зависеть от вашего домена, вы можете добавить эвристику, которая выбирает лучшую стратегию на основе входных объектов в наборе.

1 голос
/ 19 декабря 2008

Если ваша цель - производительность, то сначала избавьтесь от слова «итерация» из своего словарного запаса! научиться делать вещи в наборах.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...