Overblog
Editer l'article Suivre ce blog Administration + Créer mon blog
6 décembre 2008 6 06 /12 /décembre /2008 17:35
Bonjour,

Dans l'article précédent (http://www.lao-dba.com/article-25457591.html) nous avons vu que nous pouvions avoir des tables contenant un nombre important de lignes chainées et que cela pouvait avoir un impact pour les performances. Cela signifie qu'il faut d'une facon ou une autre il faut se débarasser de ce chainage. Alors pour cela, je vais vous proposer trois méthodes:

Méthode 1:
Une méthode connue et radicale pour éliminer les lignes chainée est tout simplement de faire un export de la table (expdp), de la supprimer et de réimporter la table (impdp).

Avantages de la méthode : Non seulement, on va supprimer les lignes chainées, mais on va également reconstruire les indexes, et remettre à le HWM (High Water Mark) a son niveau d'origine. 

Inconvénient : Si l'on est face à une table de plusieurs centaines de millions de lignes avec de nombreux indexes, cette opération peut devenier couteuse, et l'indisponibilité de la base assez longue.

Méthode 2 : 
Si on ne veut pas  passer par une opération d'import / export, il est possible d'utiliser la commande ALTER TABLE ma_table MOVE TABLESPACE Tbs
Dans mon cas, cela donne:


ALTER TABLE T_2 MOVE TABLESPACE USERS; 

Avantages de la méthode : Pas besoin d'exporter / supprimer / importer. Ce qui est peut être un plus, car nécessiterait d'octroyer des droits supplémentaires  à un user.

Inconvénient de la méthode:
En plus du fait que si la table est volumineuse, cela peut nécessiter un espace disque necessaire (le temps du move) et prendre un temps élevé, l'inconvenient majeur de cette méthode est que cela rends les indexes invalides. Et donc il faut reconstruire les indexes de la table en question. Le soucis, c'est que certains (DBA ou pas) oublient ce petit détail. Du coup on a une table qui effectivement n'a plus de lignes chainées, mais les indexes étant inutilisable (statut=UNUSABLE dans la vue USER_INDEXES), les performances vont se dégrader immediatement.
 

Methode 3:

La méthode que je vais vous proposer n'est valable que si les tables sont surveillées de façon réguilière. En effet, si on attend d'avoir 90% de lignes chainées, quel que soit la méthode, cela sera long et douloureux.
Je vais donc partir du principe que la table est surveillée, et que le % de lignes chainées est faible.
 Pour cela, on va utiliser la table CHAINED_ROWS qui non seulement nous donne le nombre de lignes chainées mais également le ROWID des lignes en question via la colonne Head_Rowid.
Le principe est simple:
  1. On crée une table temporaire avec les lignes chainées.
  2. On supprime de la table les lignes chainées.
  3. On ré-insere les lignes supprimées depuis la table temporaires.

Cela donnerait quelque chose comme:


CREATE TABLE tmp_t2 AS SELECT * FROM T_2 JOIN Chained_rows c
ON T_2.Rowid=c.Head_Rowid;

DELETE FROM T_2
WHERE Rowid IN (SELECT Head_RowId FROM Chained_Rows WHERE Table_Name='T_2';

INSERT INTO T_2 SELECT * FROM  Tmp_T2;
COMMIT;

DROP TABLE tmp_t2;



ATTENTION : En fonction du contexte, il se peut qu'il faille désactiver nos amis les contraintes et TRIGGER.
 
LAO.  
Partager cet article
Repost0

commentaires