Bonjour,
On m'a confié la mission de réindexation d'un table Oracle contenant 2 390 000 000 enregistrements (à une centaine de millions près.) L'index à modifier n'est cependant pas unique et il n'y a que 862 000 000 (à une dizaine de million près) valeur d'index différent.
La valeur d'index en question est réutilisé dans d'autres tables, mais je n'ai pas de clé étrangère pour le coup.
L'idée étant que la procédure de mise à jour ne doit pas prendre trop de temps.
Pour cela, je compte utilisé une table de travail pour la translation :
Pour l'insertion, j'hésite entre deux formules :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 -- Création de la table de travail CREATE TABLE TMP_INDEX_MAPPER_WRK ( OLDINDEX NUMBER(10) NOT NULL, NEWINDEX NUMBER(10) NOT NULL ); -- Création d'un index sur la table, car on va faire beaucoup d'accès sur celle-ci plus tard. CREATE UNIQUE INDEX PK_TMP_INDEX_MAPPER_WRK ON TMP_INDEX_MAPPER_WRK (OLDINDEX);
La version "safe", mais couteuse :
La version "performante", mais qui perdra potentiellement l'ordre.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 -- Insertion et création de la nouvelle valeur pour l'index insert into TMP_INDEX_MAPPER_WRK select MYINDEX , ROWNUM from (select distinct MYINDEX from ORIGINE) order by MYINDEX ;
Note : Pour le moment, je reste sur la version "safe"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 -- Insertion et création de la nouvelle valeur pour l'index. (Et potentiellement le nouvelle index est supérieur à l'ancien index.) insert into TMP_INDEX_MAPPER_WRK select MYINDEX , ROWNUM from (select distinct MYINDEX from ORIGINE);
Requête de vérification :
Et je mets à jour l'ensemble des tables via cette table de translation.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 -- Le nombre de cas ou l'ancienne index est inférieur au nouvelle index doit être nulle (ou très faible.) select count(*) from TMP_INDEX_MAPPER_WRK where OLDINDEX< NEWINDEX order by NEWINDEX ;
C'est sur cette requête que j'ai le plus de doute. Car, j'ai trouvé un certain nombre de requête de mise à jour pour réaliser des translation ou des jointures dans un update. Cependant, les structure de requête SQL ne passe pas la validation syntaxique de mon oracle.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 -- On met à jour l'index sur la table principale. update ORIGINE Set ORIGINE.MYINDEX = (select NEWINDEX from TMP_INDEX_MAPPER_WRK where ORIGINE.MYINDEX = TMP_INDEX_MAPPER_WRK.OLDINDEX); -- TODO Je réalise la même requête de translation sur les tables référençant l'index (probablement la même requête que celle pour la table principale)
Dans le cas de cette update, la seul crainte que j'ai est la "Double translation".
L'ensemble des updates seront dans une seul transaction et il n'y aura pas d'accès concurrent à la base de donnée.
Pouvez vous me confirmer que mon update n'est pas erronée dans ce contexte ?
Si vous avez des conseils / avis sur ce genre de manipulation, n'hésitez pas !
Cordialement,
Patrick Kolodziejczyk.
Partager