powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / проверка перед insert на существовании записи
18 сообщений из 18, страница 1 из 1
проверка перед insert на существовании записи
    #39298049
aag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть индексно-организованная простая табличка
Код: plsql
1.
2.
3.
4.
5.
create table buf (
  id number PRIMARY KEY,
  seg number,
  dt number
) organization index


Порядка 8 млн записей. Нужно проверить на существование записи с таким ИД, если нет, добавить. Если есть - ничего не делать. Вопрос в производительности. Что быстрее?
1) Селектим из таблицы по указанному ИД, если нет перехватываем exception и добавляем.
Код: plsql
1.
begin select 1 into n from buf where id = :iid,  exception when no_data_found then insert into buf ...


2) тоже самое, через агрегат, чтобы избежать exception
Код: plsql
1.
select max(1) into n from buf where id = :iid, 

если n is NULL - добавляем
3) Сразу пытаемся вставить, если не получилось - ну хорошо, идем дальше.
Код: plsql
1.
begin insert into buf exception when DUP_VAL_ON_INDEX then NULL; end;



Все это часть большого пакета, который дергается в неком общем процессе, после которого работает еще куча таких же больших; поэтому вопрос скорости важен. Что подкажете?
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298055
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Merge
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298104
aag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

Хм. Потестил, как мог. Дело в том, что добавление идет в цикле, построчно.
Для merge пришлось изворачиваться через cte

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
	loop
		merge into test_buf t
		using
		(
			with cte as (select x.id, x.seg, x.dtfirst from dual) select id, seg, dtfirst from cte 
		) s
		on (t.seg = s.seg)
		when not matched then
			insert (t.id, t.seg, t.dtfrom) values(s.id, s.seg, s.dtfirst);
	end loop;


Возможно, я неправильно merge готовлю. Но варианту с лобовым insert и игнорированием исключения он проиграл почти в два раза.
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298111
__vvp_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aag,

Данные откуда идут?
Может не нужен цикл?
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298120
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aagДело в том, что добавление идет в цикле, построчно.
1. Избавиться от цикла, если он на базе источника данных.
2. Если цикл суть генератор данных, то можно либо перевести генерацию на запрос, либо заменить построчные операции с БД на подготовку массива с последующим FORALL insert SAVE EXCEPTIONS.

В любом случае - если бы абстрактные вопросы производительности имели конкретные ответы, то мир вокруг был бы иным.
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298135
aag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

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

авторесли бы абстрактные вопросы производительности имели конкретные ответы,
Ну, оно так, конечно. С другой стороны, я боялся наткнуться на какие-нибудь нюансы обработки Ораклом исключений в плане производительности. Их в теории желательно было бы избегать же.
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298145
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousMergeвсе равно оборачивать в перехват исключения на уникальность.
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298146
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aagЕсть индексно-организованная простая табличка
Код: plsql
1.
2.
3.
4.
5.
create table buf (
  id number PRIMARY KEY,
  seg number,
  dt number
) organization index


Порядка 8 млн записей. Нужно проверить на существование записи с таким ИД, если нет, добавить. Если есть - ничего не делать. Вопрос в производительности. Что быстрее?


Любой select перед insert - это фикция. Или merge или вариант 3
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298162
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-andrey_anonymousMergeвсе равно оборачивать в перехват исключения на уникальность.
Ы?
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298191
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous-2-пропущено...
все равно оборачивать в перехват исключения на уникальность.
Ы?в первых двух вариантах проверка селектом не гарантирует невозбуждение исключения. это отличается от третьего варианта, вероятно с ожидаемым для автора поведением.
merge по поведению равносилен первым двум вариантам.
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298311
Nobody1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
можно ещё обойтись хинтом в инсерте, ignore_dup_val_on_index, кажется. В 11.2 и выше точно есть
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298443
Nobody1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
поправка, хинт такой /*+ IGNORE_ROW_ON_DUPKEY_INDEX(tablename, indexname)*/
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298474
Nobody1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а вот тут https://iusoltsev.wordpress.com/2013/12/29/ignore_row_on_dupkey_index/ Усольцев показывает, что этот хинт по производительности сливает, а рулит создание view с instead of insert триггером. Но это, конечно, проверить лучше.
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298493
Фотография orawish
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну если уж (из ничего ) пошла такая пьянка,
то можно и про (dml) log errors кляузу вспомнить
только если сливаться туда будет много строк (10% это много), то
скорость сядет на порядок

баян
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298507
aag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schi, -2-

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

Nobody1111
В моем случае, этот хинт по скорости совпал с обычной проверкой исключения при инсерте.

Но вообще интересно.
Провел два теста. В тестовой таблице 1 млн записей, в первом случае шло примерно 10% уже существующих значений (которые должны были быть отвергнуты), 90% новых. Победил с разгромным счетом инсерт с проверкой на исключение.
Во втором случае, наоборот 95% добавляемых записей уже были в тестовой таблице, и только 5% новых.
Выиграл вариант с проверкой селектом. Мерж отстал немного, где-то на треть. Инсерт провалился с треском - время выполнения было больше почти в 4 раза.
ЗЫ. Естественно, тесты выполнялись несколько раз.
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298508
aag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
orawish,

мне это не совсем нужно.
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298521
Фотография orawish
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aagorawish,

мне это не совсем нужно.
предположу, что в ваших (неестественно тепличных) условиях победит
инсерт селект минус
...
Рейтинг: 0 / 0
проверка перед insert на существовании записи
    #39298663
aag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
orawishaagorawish,

мне это не совсем нужно.
предположу, что в ваших (неестественно тепличных) условиях победит
инсерт селект минус
В конце концов, так и сделал. Вынес из цикла, обернул в мерж.
Условия совсем не тепличные, просто это хранилище со своей спецификой. 10 млн записей туда, 20 сюда...
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / проверка перед insert на существовании записи
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]