Как плохо игнорирует Oracle исключение DUP_VAL_ON_INDEX?

Вы можете использовать подстановку команд:

[root@ip-10-0-0-136 ~]# $(echo hi)

, которая идентична

[root@ip-10-0-0-136 ~]# `echo hi`
10
задан OMG Ponies 30 September 2009 в 18:31
поделиться

4 ответа

Я обычно просто вставлял бы и захватывал бы исключение DUP_VAL_ON_INDEX, поскольку это является самым простым кодировать. Это более эффективно, чем проверка существование перед вставкой. Я не считаю выполнение этого "неприятным запахом" (ужасная фраза!), потому что исключение мы обрабатываем, повышен Oracle - это не похоже на повышение Ваших собственных исключений как механизм управления потоком.

Благодаря комментарию Igor я теперь выполнил два различных сравнительных теста на этом: (1) где все вставляют попытки кроме первого, дубликаты, (2) где все вставляет, не дубликаты. Действительность будет находиться где-нибудь между этими двумя случаями.

Примечание: тесты, выполненные на Oracle 10.2.0.3.0.

Случай 1: Главным образом дубликаты

Кажется, что самый эффективный подход (значимым фактором) должен проверить на существование ПРИ вставке:

prompt 1) Check DUP_VAL_ON_INDEX
begin
   for i in 1..1000 loop
      begin
         insert into hasviewed values(7782,20);
      exception
         when dup_val_on_index then
            null;
      end;
   end loop
   rollback;
end;
/

prompt 2) Test if row exists before inserting
declare
   dummy integer;
begin
   for i in 1..1000 loop
      select count(*) into dummy
      from hasviewed
      where objectid=7782 and userid=20;
      if dummy = 0 then
         insert into hasviewed values(7782,20);
      end if;
   end loop;
   rollback;
end;
/

prompt 3) Test if row exists while inserting
begin
   for i in 1..1000 loop
      insert into hasviewed
      select 7782,20 from dual
      where not exists (select null
                        from hasviewed
                        where objectid=7782 and userid=20);
   end loop;
   rollback;
end;
/

Результаты (после того, как, работая однажды, чтобы не анализировать издержки):

1) Check DUP_VAL_ON_INDEX

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.54
2) Test if row exists before inserting

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.59
3) Test if row exists while inserting

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.20

Случай 2: никакие дубликаты

prompt 1) Check DUP_VAL_ON_INDEX
begin
   for i in 1..1000 loop
      begin
         insert into hasviewed values(7782,i);
      exception
         when dup_val_on_index then
            null;
      end;
   end loop
   rollback;
end;
/

prompt 2) Test if row exists before inserting
declare
   dummy integer;
begin
   for i in 1..1000 loop
      select count(*) into dummy
      from hasviewed
      where objectid=7782 and userid=i;
      if dummy = 0 then
         insert into hasviewed values(7782,i);
      end if;
   end loop;
   rollback;
end;
/

prompt 3) Test if row exists while inserting
begin
   for i in 1..1000 loop
      insert into hasviewed
      select 7782,i from dual
      where not exists (select null
                        from hasviewed
                        where objectid=7782 and userid=i);
   end loop;
   rollback;
end;
/

Результаты:

1) Check DUP_VAL_ON_INDEX

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.15
2) Test if row exists before inserting

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.76
3) Test if row exists while inserting

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.71

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

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

14
ответ дан 3 December 2019 в 22:02
поделиться

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

1
ответ дан 3 December 2019 в 22:02
поделиться

Попробовать это?

SELECT 1
FROM TABLE
WHERE OBJECTID = 'PRON_172.JPG' AND
      USERID='JCURRAN'

Это должно возвратиться 1, если существует тот там, В ДРУГИХ ОТНОШЕНИЯХ ПУСТОЙ.

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

1
ответ дан 3 December 2019 в 22:02
поделиться

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

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

0
ответ дан 3 December 2019 в 22:02
поделиться
Другие вопросы по тегам:

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