2010-03-29 5 views
1

Je recherche la meilleure solution (performance sage) pour y parvenir.Oracle: Insertion sur une table indexée, évitant les doublons. Vous cherchez des conseils et des conseils

Je dois insérer des enregistrements dans une table, en évitant les doublons.

Par exemple, prenez le tableau 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 
) 
); 

J'ai un index de A.SOMEKEY, pour optimiser le PAS EXISTE requête, mais je me rends compte que l'insertion sur une table indexée sera une baisse de performance. Je pensais donc à dupliquer le tableau A dans une table temporaire globale, où je conserverais l'index. Ensuite, en supprimant l'indice du tableau A et l'exécution de la requête, mais modifié

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 
) 
); 

Cela résoudrait le « insertion sur une table d'index », mais je dois mettre à jour le Global Temporaire A avec chaque insertion que je fais.

Je suis un peu perdu ici,

est-il une meilleure façon d'y parvenir?

Merci à l'avance,

+0

Est-ce une chose une seule fois? Avez-vous prouvé que le coup que vous prenez en laissant l'index en place est assez mauvais pour justifier un travail? – Kuberchaun

+0

Quelle version d'Oracle exécutez-vous? – Kuberchaun

+0

@ StarShip3000: Non, c'est un processus nocturne. Je crois que la version oracle est 11g. – Tom

Répondre

2

si la colonne A.SOMEKEY est déclarée NOT NULL et si vous insérez une grande amound de données, un NOT IN clause pourrait être plus efficace que vous n'êtes pas EXISTE car il sera en mesure d'utiliser un HASH ANTI-JOIN. HASH ANTI-JOINS sont brutalement efficaces avec de grands ensembles de données.

Je ne pense pas que la table temporaire est une bonne idée dans ce cas parce que vous serez dans l'un de ces deux cas:

  1. la table temporaire est indexée sur SOMEKEY, votre point sur l'insertion dans un table indexée étant donc sans objet
  2. la table temporaire est non indexée et votre anti-jointure sera inefficace

Quelle méthode est la plus efficace sera probablement dépend du volume de données.

+0

Les volumes de données devraient être "grands" – Tom

0

Que diriez-vous d'avoir l'index sur la table A. create table b (même structure que le tableau a) avec 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 
) 
); 

basculons alors l'index A et INSERT INTO A SELECT * FROM B

Vous pourriez faire B une table temporaire globale, mais assurez-vous que les données sont persistantes pour la session car la suppression de l'index impliquera implicitement.

Questions connexes