Oracle: вставка в индексированную таблицу, избегая дублирования. Нужны советы и рекомендации - PullRequest
1 голос
/ 29 марта 2010

Я ищу лучшее решение (с точки зрения производительности) для достижения этой цели.

Я должен вставлять записи в таблицу, избегая дублирования.

Например, возьмем таблицу A

Insert into A (
 Select DISTINCT [FIELDS] from B,C,D.. 
 WHERE (JOIN CONDITIONS ON B,C,D..)
 AND 
 NOT EXISTS
 ( 
   SELECT * FROM A ATMP WHERE
   ATMP.SOMEKEY = A.SOMEKEY
 )
);

У меня есть индекс над A.SOMEKEY, просто для оптимизации запроса NOT EXISTS, но я понимаю, что вставка в индексированную таблицу будет снижать производительность.

Итак, я думал о дублировании таблицы A в глобальной временной таблице, где я буду хранить индекс. Затем, удалив индекс из таблицы A и выполнив запрос, но изменив

Insert into A (
 Select DISTINCT [FIELDS] from B,C,D.. 
 WHERE (JOIN CONDITIONS ON B,C,D..)
 AND 
 NOT EXISTS
 ( 
   SELECT * FROM GLOBAL_TEMPORARY_TABLE_A ATMP WHERE
   ATMP.SOMEKEY = A.SOMEKEY
 )
);

Это решило бы «вставку в индексную таблицу», но мне пришлось бы обновлять глобальное временное «А» с каждой сделанной мной вставкой.

Я как бы потерялся здесь,

Есть ли лучший способ добиться этого?

Заранее спасибо,

Ответы [ 2 ]

2 голосов
/ 29 марта 2010

, если столбец A.SOMEKEY объявлен NOT NULL и если вы вставите большой объем данных, предложение NOT IN может быть более эффективным, чем ваш NOT EXISTS, так как он сможет использовать HASH ANTI-JOIN.

INSERT INTO A
   (SELECT DISTINCT FIELDS
      FROM B, C, D ..
     WHERE (JOIN CONDITIONS ON B, C, D..)
       AND [B].SOMEKEY NOT IN (SELECT SOMEKEY FROM A)
       AND [B].SOMEKEY IS NOT NULL;

HASH ANTI-JOINS чрезвычайно эффективны с большими наборами данных.

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

  1. временная таблица индексируется на SOMEKEY, поэтому ваше мнение о вставке в индексированную таблицу является спорным
  2. временная таблица неиндексируется, а ваше объединение будет неэффективным

Какой метод наиболее эффективен, вероятно, зависит от объема данных.

0 голосов
/ 30 марта 2010

Как насчет наличия индекса в таблице А. создать таблицу b (такая же структура, как у таблицы a) с помощью NOLOGGING

Insert /*+APPEND */ into b (
 Select DISTINCT [FIELDS] from B,C,D.. 
 WHERE (JOIN CONDITIONS ON B,C,D..)
 AND 
 NOT EXISTS
 ( 
   SELECT * FROM A ATMP WHERE
   ATMP.SOMEKEY = A.SOMEKEY
 )
);

Затем сбросьте индекс на A и INSERT INTO A SELECT * FROM B

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

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