2012-06-22 3 views
2

J'ai une table contenant quelques milliards d'enregistrements et j'ai juste besoin de mettre à jour un seul champ sans condition.Oracle essayant de mettre à jour une colonne

update <table name> set flag='N' Ceci est ma requête de mise à jour, cela prend beaucoup de temps. Comment faire cela rapidement.

+0

utilisez d'abord l'indexation puis exécutez la mise à jour! – vijay

+2

Asha n'a pas de condition, donc l'indexation de la table n'aidera pas. En plus de cela, la création de l'index prendra probablement plus de temps que la mise à jour de toute façon. –

+0

@Asha: Vous devrez probablement vivre avec ... –

Répondre

0

Ne pas mettre à jour. Utilisez CTAS, puis renommez la nouvelle table.

CREATE TABLE T_NEW NOLOGGING PARALLEL AS 
SELECT COL1, COL2, 'N' FLAG FROM T_OLD; 

Appliquez ensuite des index, des contraintes ou des subventions de votre ancienne table. Si vous oubliez cette étape, vous allez souffrir.

DROP TABLE_T_OLD; 
RENAME T_NEW TO T_OLD; 

Essayez d'être prudent car vous laisser tomber la vieille table.

0

Première ideea: Si vous avez l'espace:

create table tmp_tab as select col1, ..., coln, "N" as flag 
    from your_tab; 

    rename table your_tab to your_tab_old; 

    rename tmp_tab to your_tab; 

sera très rapide par rapport à la mise à jour simple.

Déposez votre_tab_old si tout va bien.

Deuxième ideea:

update /*+parallel(your_tab 8)*/ your_tab set flag='N';

sera plus rapide que la version NOPARALLEL.

2

Si vous vraiment ne pouvez pas attendre aussi longtemps pour lancer votre mise à jour, et peut vivre avec le drapeau étant nul au lieu de « N », alors vous pouvez le faire très rapidement (non testé, mais devrait fonctionner):

Vous pouvez par la suite supprimer les points de contrôle inutilisés si vous souhaitez récupérer de l'espace (notez que la suppression prendra un certain temps, donc faites attention si vous choisissez de le faire).

espoir qui aide

EDIT: Merci à @TTT pour cette article, apparemment dans Oracle 11g peut stocker une valeur par défaut dans le dictionnaire de données plutôt que d'effectuer une mise à jour toutes les lignes (ce que je pensais des expériences précédentes) . Cela signifie que vous pouvez utiliser la valeur 'N' au lieu de NULL. Assurez-vous que vous spécifiez NOT NULL, ainsi que la valeur par défaut:

SQL> set timing on 
SQL> drop table test1 
Table dropped. 
Elapsed: 00:00:00.23 

SQL> create table test1 
(
col1 varchar2(10), 
flag char(1) 
) 
Table created. 
Elapsed: 00:00:00.14 

SQL> insert into test1 
select 'x','Y' 
from dual 
connect by level <= 1000000 
1000000 rows created. 
Elapsed: 00:00:02.09 

SQL> alter table test1 set unused column flag 
Table altered. 
Elapsed: 00:00:00.07 

SQL> alter table test1 add (flag char(1) default 'N' not null) 
Table altered. 
Elapsed: 00:00:01.01 

Sans la « NOT NULL » et juste un défaut, il a fallu plus de 20 secondes, montrant cette astuce « rapide = true » ne fonctionne lors de la spécification non nulle et un défaut (ce qui a vraiment du sens).

+0

Je pense que vous pouvez ajouter une colonne non nulle avec une valeur par défaut sans avoir à attendre des minutes ou des heures.Cela devrait prendre seulement 1 seconde environ. Lisez ici: http://oracletoday.blogspot.nl/2007/10/fasttrue-for-adding-columns-in-11g.html – TTT

+0

@TTT Merci pour le lien. Je pense que la valeur par défaut de 'N' prendrait du temps pour un milliard de lignes, mais je peux me tromper (peut-être 11g gère différemment). – tbone

+0

@TTT Merci encore, l'article est très intéressant. Je vais faire un test rapide et mettre à jour ma réponse avec une valeur par défaut si 11g n'a vraiment PAS besoin de faire la mise à jour avec les valeurs par défaut! – tbone

Questions connexes