2008-12-13 4 views
1

Depuis que j'ai lancé le processus d'insertion de 7M lignes d'une table dans deux autres, je me demande maintenant s'il existe un moyen plus rapide de le faire. Le processus devrait se terminer dans une heure, soit 24 heures de traitement.Insertion plus rapide Table Oracle Hash Cluster

Voilà comment ça se passe:

Les données de ce tableau

RAW (word VARCHAR2(4000), doc VARCHAR2(4000), count NUMBER); 

devrait trouver une nouvelle maison dans deux autres tables de cluster T1 et T2

CREATE CLUSTER C1 (word VARCHAR2(4000)) SIZE 200 HASHKEYS 10000000; 
CREATE CLUSTER C2 (doc VARCHAR2(4000)) SIZE 200 HASHKEYS 10000000; 

T1 (word VARCHAR2(4000), doc VARCHAR2(4000), count NUMBER) CLUSTER C1(word); 
T2 (doc VARCHAR2(4000), word VARCHAR2(4000), count NUMBER) CLUSTER C2(doc); 

par Java inserts avec manuel Commettre comme ceci

stmtT1 = conn.prepareStatement("insert into T1 values(?,?,?)"); 
stmtT2 = conn.prepareStatement("insert into T2 values(?,?,?)"); 

rs = stmt.executeQuery("select word, doc, count from RAW"); 

conn.setAutoCommit(false); 

while (rs.next()) { 
    word = rs.getString(1); 
    doc = rs.getString(2); 
    count = rs.getInt(3); 

    if (commitCount++==10000) { conn.commit(); commitCount=0; } 

    stmtT1.setString(1, word); 
    stmtT1.setString(2, doc); 
    stmtT1.setInt(3, count); 

    stmtT2.setString(1, doc); 
    stmtT2.setString(2, word); 
    stmtT2.setInt(3,count); 

    stmtT1.execute(); 
    stmtT2.execute(); 
} 

conn.commit(); 

Des idées?

Répondre

3

La première chose que je recommande est de faire une simple instruction insert-select, et de laisser la base de données gérer tout le mouvement de données. Cela n'est pas très utile si vous déplacez des données entre deux ordinateurs ou si vous n'avez pas de segment de restauration suffisamment important pour gérer l'ensemble de la requête.

La deuxième chose que je dois apprendre à propos de la méthode addBatch(). Lorsque vous avez écrit votre code, celui-ci effectue un aller-retour vers la base de données pour chaque ligne que vous insérez, ce qui ajoute une surcharge réseau. Troisièmement, à moins que vous ayez déjà beaucoup de lignes dans les tables de destination, vous devez supprimer les index avant vos insertions et les recréer ensuite. Si vous laissez les index en place, ils doivent être mis à jour pour chaque ligne, en ajoutant le surcoût du bloc sale.

Et enfin: avez-vous besoin de tables groupées? Mon expérience a été qu'ils ne vous achètent pas beaucoup (mise en garde: cette expérience était sur un seul espace de table).

+0

hé merci pour vos conseils. J'utilise Java pour surveiller le processus de transfert de données (combien de lignes restantes), un INSERT AS SELECT normal ne me le dit pas. J'accède toujours aux tables de la même manière, comme select * from T1 où word = 'foo'; pour ce que les tables de hachage sont les meilleurs je pense. – chris

+0

Basé sur l'expérience passée avec les bases de données indexées par hachage (Teradata), je ne ferais appel aux clusters de hachage que si vous joignez plusieurs tables sur la même clé - et comme je l'ai remarqué, je ne voyais pas grand intérêt. Pour votre requête, un index B-tree normal est probablement le meilleur. – kdgregory

+0

Si vous utilisez la syntaxe INSERT INTO .. ​​SELECT FROM, vous pouvez utiliser v $ longops pour voir où cela se passe. –

0

À moins que vous n'ayez une raison particulière de gérer des données dans l'application, j'irais directement à INSERT AS SELECT. L'utilisation de Parallel DML peut vous donner une énorme différence.

Vérifiez également la syntaxe INSERT ALL (1 lecture pour 2 écritures) si cela correspond à vos besoins.

Sauf si vous avez des problèmes IO, 1 h devrait être plus que suffisant ...

Cordialement

1

Eh bien, vous ne pouvez pas appeler une table RAW dans Oracle - c'est un mot réservé si un ora- 00903 erreur sera soulevée.

Cela mis à part, vous utiliseriez:

insert all 
into t1 
into t2 
select * from RAW 
/

« ligne par ligne est égale à lent par lent » :)

0

conceptuellement similaire à addBatch, vous pouvez écrire une procédure PL/SQL qui accepte les tableaux de (word, doc, count) et traite les insertions côté serveur. Il est conceptuellement similaire puisque vous réduisez les voyages sur le réseau en envoyant plusieurs enregistrements en une fois et vous pouvez obtenir des performances plus rapides. D'un autre côté, il est plus compliqué et fragile car il nécessite l'écriture du PL/SQL côté serveur et nécessitera une logique de réseau supplémentaire côté client. Oracle TechNet en a quelques exemples.

// Nicholas

Questions connexes