Overblog
Editer l'article Suivre ce blog Administration + Créer mon blog
4 décembre 2008 4 04 /12 /décembre /2008 20:19
Bonsoir,

Pour commencer ce mois de décembre,  on va laisser un petit les nouveautés d'ORACLE 11 et revenir à notre quotidien : A savoir, les problèmes de performance.
Lorsque vous (ou un de vos clients) a des problèmes de performance une chose que beaucoup oublient de vérifier est le pourcentage de lignes chainées. Et pourtant ceci, peut avoir un impact non négligeable sur les performances.

Qu'est ce qu'une ligne chainée ?

Lors de la création d'une table, vous définissez une valeur pour le paramètre PCTFREE. La, je suis un peu optimiste. En admettant que vous ne soyez pas DBA, ou qu'Oracle n'est pas votre quotidien, vous créez une table avec 10 comme valeur pour PCTFREE. Il s'agit de la valeur par défaut. L'unité de mesure d'un tablespace  étant le block, cela signifie que lorsque vous inserez des lignes dans une table, oracle gardera 10% d'espace libre par block pour les futures mises à jour (update).
Si lors d'une mise à jour, il n'y a plus d'espace dans le block contenant la ligne, Oracle mettre l'information dans un autre block qui sera chainée via le ROWID (numéro de sécu de la ligne).
Le souci, c'est que lorsque l'on va vouloir récupérer des informations de la table portant sur une ligne chainée, Oracle devra lire deux blocks au lieu d'un, et c'est la que les performances peuvent se dégrader. Car si un trop grand nombre de lignes sont chainées, on va multiplier les lectures.

Alors maintenant que l'on sait ce qu'est une ligne chainée; comment fait-on pour les identifier ?

 Ce n'est pas très compliqué, il suffit d'analyzer la table voulue avec la commande suivante:


ANALYZE TABLE ma_table LIST CHAINED ROWS INTO Chained_Rows;



Et la ! forte probalité d'avoir une belle ORA-01495, table de ligne de chaine indiquée introuvable.
 
Comme souvent Oracle offre des outils, mais l'installation par défaut les laisse de coté.
Il faut créer la table Chaine_Rows
Pour cela vous pouvez utiliser le script utlchain.sql qui se trouve dans $ORACLE_HOME\RDBMS\admin

Il s'agit simplement d'un CREATE TABLE. Comme je suis gentil, je vous mets le script.




create table CHAINED_ROWS (
  owner_name         varchar2(30),
  table_name         varchar2(30),
  cluster_name       varchar2(30),
  partition_name     varchar2(30),
  subpartition_name  varchar2(30),
  head_rowid         rowid,
  analyze_timestamp  date
);



Elle s'appelle CHAINED_ROWS, rien ne vous empeche de l'appeler autrement. Disons que c'est plus sage.
Soit vous créer la table dans le schema pour lequel vous voulez analyzer des tables ou alors vous la créer sur un schema  à part (voir en SYSTEM), en prenant soin de créer un synonym public.

Donc une fois la table crée, on peut relancer l'analyze.

Juste pour la forme un petit exemple tout simple.




CREATE TABLE T_2 (col1 number, col2 number);

BEGIN
   FOR i IN 1..100000 LOOP
      INSERT INTO T_2 VALUES (i,1);
   END LOOP;
   COMMIT;
END;
/


 
et puis un jour, le fonctionnel changeant (si si , ca arrive), on décide d'ajouter une colonne col3 de type NVARCHAR2(50)
 

 

ALTER TABLE T_2 ADD (col3 nvarchar2(50));


et comme si ca ne suffisait pas on décide de l'initialiser avec la valeur "VIDE" (j'en connais qui font ca)


UPDATE T_2 SET COL3='VIDE';
COMMIT;




 Et bien de facon inconsciente, vous venez de participer à la dégradation des performances de votre base.
 
Démonstration:


ANALYZE TABLE T_2 LIST CHAINED ROWS INTO CHAINED_ROWS;
SELECT COUNT(*) FROM CHAINED_ROWS;


 
 Résultat :plus de 69000 lignes chainées dans mon cas (taille de block=8K). 70% de lignes chainées alors qu'Oracle recommande d'agir à partir de 5% de lignes chainées.

 Essayez de projeter cela sur un schema avec de nombreuses tables contenant de nombreuses colonnes, et vous comprendrez mieux pourquoi votre base rame !


ATTENTION
: Ne pas confondre les "lignes chainées" avec la valeur le la colonne CHAIN_CNT de la table USER_TABLES.


Et après, maintenant que l'on sait ou se trouve le mal, il sera plus simple de l'éradiquer !
Allez je vous laisse réfléchir un petit peu sur le sujet, et on en reparle demain ou lundi. NE soyez pas timides, faites des propositions !!

 
LAO

 
Partager cet article
Repost0

commentaires

E
<br /> <br /> la problématique des lignes chainées est-elle toujours un pb dans le environnements actuels en 10g ou 11g associé un serveur /san.<br /> <br /> <br /> As-tu un exemple précis de dégradation de performance liée à ce phénomène ?  qui est décrit dans les bouquins de tuning mais que je n'ai jamais observé. A partir du moment où tu paramètres<br /> convenablement ta sga pour avoir un bon hit ratio, l'overhead engendré par les listes chainées me parait marginal.<br /> <br /> <br /> <br />
Répondre
L
<br /> <br /> Bonjour,<br /> <br /> <br /> D'exemple vécu :non. Mais je pense que sur une forte volumétrie cela peut avoir un impact. On a beau tailler une SGA élevé, dans le cas de traitement batch ou décisionnel qui feraient des FULL<br /> sur de grosses tables, on ne pourra pas avoir toute la base en mémoire et par conséquent, si on peut limiter les IO en supprimant le chainage (si il devient conséquent ) peut avoir un impact.<br /> <br /> <br /> Sinon j'ai vu que tu avais également un blog sur Oracle. Je peux l'ajouter dans mes liens si tu le désires.<br /> <br /> <br /> @+<br /> <br /> <br /> <br />