Mohamed Houri a traduit un chapitre de Jonathan Lewis sur le Clustering Factor qui est si important dans le coùt d'accès à une table via un index.
Voici le lien de la traduction en français: http://jonathanlewis.files.wordpress.com/2011/05/le-clustering-factor.pdf
Jonathan Lewis a mis les liens de l'article original et de la traduction sur son blog.
Vous devez être identifié pour poster un commentaire.
Ceci est une traduction de d'un ancien post de Jonathan Lewis sur forums.oracle.com, référencé récemment sur son blog. Il décrit le fonctionnement de la journalisation en mémoire (IMU - In Memory Undo), une optimisation introduite en 10g qui utilise des structures en mémoire pour diminuer la contention sur les blocs d'undo et le redo log buffer.
Le contenu des blocs d'undo et des fichiers de redo log sont quasiment les même que l'on utilise in-memory undo (et les private redo threads) ou que l'on utilise la journalisation 'normale'.
La principale différence se trouve dans l'ordre où sont faites les choses.
Il y a aussi, avec in-memory undo, une diminution du nombre de redo records même si le nombre de change vectors reste le même.
Voici le séquencement d'une transaction courte avec gestion normale de la journalisation.
Si l'on insère 10 lignes, une par une, dans une table qui a 4 indexes, alors on va générer 50 redo records et 50 undo records, et faire appel 50 fois au latches de redo: 5 redo record par ligne (un pour la table et un pour chaque index) pour 10 lignes.
Lorsque la fonctionnalité de journalisation en mémoire (in-memory undo) est activée, et parce que dans cet exemple il s'agit d'une petite transaction, voici ce qu'il se passe:
Il y a de nombreux détails et variations autour de ce qui se passe là. Par exemple au début et à la fin de la transaction, ou lorsque un des deux buffers est plein (puisqu'ils ne font que 64Ko ou 128Ko) mais la description faite ci-dessus couvre les différences essentielles.
Question: Supposons que je démarre l'instance et effectue quelques mises à jour. J'ai donc un buffer privé de redo et un buffer privé de undo, créés en shared pool. Immédiatement après le système se plante et rien n'est encore écrit dans les fichiers de redo ni dans les blocs d'undo. Dans cette situation comment fait Oracle pour récupérer les données d'undo ?
Il y a deux chose que vous devez prendre en compte dans ma description:
Si la session a fait un commit, elle a écrit le redo privé dans le redo thread public, qui doit être écrit sur disque avant que le commit ne soit terminé. Donc il n'y a rien de différent au niveau du recovery.
Maintenant, si la session n'a pas encore fait de commit, alors du point de vue des autres utilisateurs, rien ne s'est encore passé (ils ne sont censés voir que les effets des transactions commitées). Du coup, cela n'a pas d'importance que les redo et undo privés aient disparu.
Mais voici où ca devient plus complexe: Comment les autres sessions voient que vous êtes en train de modifier les mêmes blocs qu'elles, si vous ne les mettez à jour que lorsque vous faites le commit de votre transaction ? Comment Oracle fait pour minimiser le temps que prennent toutes les modifications de blocs qui doivent être faites lors du commit ? J'ai quelques réponses à ces questions, mais elles ne sont ni exactes, ni complètes, alors je ne préfère pas les publier.
Cependant, un point clé de ce mécanisme, c'est le fait qu'il ne s'applique qu'à des petites transactions. Les zones privées ne font que 64Ko ou 128Ko suivant qu'on est en 32 ou 64 bits, et dès que la transaction devient trop grande, Oracle les écrit dans les redo buffer et poursuit avec le mécanisme normal.
Vous devez être identifié pour poster un commentaire.
, Pachot Franck Ceci est une traduction de d'un post de Jonathan Lewis sur son blog - la quatrième et dernière partie d'une série de quatre sur la fragmentation (original en anglais). Il est conseillé de lire avant: Fragmentation - Introduction, Fragmentation - Disque et Tablespace, Fragmentation - Table
La fragmentation en extents multiples et la fragmentation due à ASSM que j'ai décrit dans la note précédente à propos des tables s'appliquent aussi aux indexes, bien sûr, et nous importe de la même manière, c'est à dire presque jamais. Lorsque les gens parlent de fragmentation d'index, ils pensent en général au problème des blocs avec un faible taux de remplissage (sparsely populated blocks) qui est aussi un phénomène que j'ai décrit à propos de la fragmentation des tables, mais il y a quelques différences entre une table et un index, que nous allons examiner tout de suite.
Il est intéressant de considérer aussi un autre sens possible pour la fragmentation d'un index, que nous allons aussi examiner: c'est l'effet de bord de la division d'un bloc feuille (leaf block splitting) qui fait que des blocs qui sont logiquement à la suite se retrouvent physiquement dispersés.
Vous devez être identifié pour poster un commentaire.
, Pachot Franck Ceci est une traduction de d'un post de Jonathan Lewis sur son blog - la troisième partie d'une série de quatre sur la fragmentation (original en anglais). Il est conseillé de lire avant: Fragmentation - Introduction, Fragmentation - Disque et Tablespace
Dans l'introduction nous avons parlé d'un type de fragmentation au niveau table qui, en général, ne pose pas de problème: la fragmentation d'une table en plusieurs extents. Et il y a une chose amusante, c'est que ASSM (Automatic Segment Space Management - la gestion automatique de l'espace libre dans les segments) a introduit une nouvelle forme de fragmentation, mais qui ne pose généralement pas de problème non plus.
Vous devez être identifié pour poster un commentaire.
, Pachot Franck Ceci est une traduction de d'un post de Jonathan Lewis sur son blog - la deuxième partie d'une série de quatre sur la fragmentation (original en anglais). Il est conseillé de lire avant: Fragmentation - Introduction
Les tablespaces sont composés de fichiers, et les fichiers sont stockés sur disque. Il s'agit la plupart du temps de disques logiques (logical volumes) plutôt que de vrais disques directement (real devices).
Lorsqu'on fait une lecture sur un vrai disque, la taille des données qu'on peut lire en une seule opération physique est quelque chose comme 400Ko ou 500Ko. C'est le contenu d'une seule piste sur un seul plateau d'un disque physique. Une lecture plus large continue en passant sur un autre plateau (ce n'est pas un mouvement physique des têtes, mais une commutation 'électronique') , ou bien en passant sur une autre piste (c'est alors un mouvement physique, mouvement latéral de la tête), ou encore en passant sur un autre disque. Passer sur un autre disque, c'est rejoindre une autre file d'attente de disque, et dans ce cas le logiciel du SAN, ou l'équivalent, aura probablement anticipé les disques dont vous aurez besoin et aura lancé en parallèle ces demandes de lectures dans les files d'attentes correspondantes.
Vous devez être identifié pour poster un commentaire.
, Pachot Franck Ceci est une traduction d'un post de Jonathan Lewis sur son blog - la première partie d'une série de quatre sur la fragmentation (original en anglais)
Cet article a commencé comme une note brève, jusqu'à ce que je réalise que ça allait être plus important, et que j'en fasse plutôt une série de quatre articles:
Le mot 'fragmentation' donne l'idée de quelque chose qui est cassé en plusieurs morceaux, mais il a aussi une connotation émotionnelle qui fait penser qu'il y a beaucoup de petits morceaux. Dans le contexte d'une base Oracle, vous devez savoir ce que vous entendez par 'morceau', ainsi que la granularité de ces morceaux, et leur impact possible sur les performances.
Vous devez être identifié pour poster un commentaire.
Cet article est la traduction d'un article de Jonathan Lewis publié sur son blog. L'article original en anglais se trouve ici.
Pour une description complète des modes de verrous, vous pouvez lire aussi: Les verrous sur les table, et leurs modes (S/X/RS/RX/SRX)
A propos des verrous (locks) et de leur mode (dans les colonnes LMODE et REQUEST de la vue V$LOCK par exemple), je raisonne souvent avec leur numéro. Et je m'apercois que je n'arrive jamais à retenir la correspondance entre le numéro et le lien, sauf pour le mode 6 = exclusive. Donc j'ai finalement mis ici la table de correspondance pour que je puisse la retrouver facilement.
Vous devez être identifié pour poster un commentaire.
Cet article est la traduction d'un article de Jonathan Lewis publié sur son blog. L'article original en anglais se trouve ici.
Le ROWID identifie un enregistrement d'une table dans la base de données, à partir de l'adresse physique du bloc et du numéro d'enregistrement dans le bloc. Il est utilisé principalement dans les indexes pour pointer sur l'enregistrement de la table, et dans les tables pour les pointeurs des chained rows. C'est le moyen le plus direct car il permet d'aller directement sur le bloc qui contient l'enregistrement.
Jusqu'à Oracle 7, l'adresse physique d'un bloc était constitué du numéro du fichier de la base (absolute file_number, AFN ou FILE_ID ou FILE#) et du numéro de bloc relatif au fichier (block_number ou BLOCK_ID ou BLOCK#). L'ensemble est appelé DBA: Data Block Address. Le ROWID utilise cela pour identifier le bloc, et y ajoute le numéro d'enregistrement dans le bloc (ROW_NUMBER ou ROW#).
A partir d'Oracle 8, l'identification des fichiers est relative au tablespace. Cela permet de supporter plus de fichiers dans une base, et de rendre les tablespaces plus indépendants. On parle alors de numéro de fichier relatif à la tablespace (relative file_number, RFN ou RELATIVE_FNO ou RFILE#). Avec le numéro de bloc relatif au fichier, l'ensemble constitue le RDBA: Relative Data Block Address. Pour les bigfile tablespaces, ne comportant qu'un seul fichier, il s'agit seulement du block#.
Pour trouver un bloc dans la base, il est donc nécessaire de connaître aussi le tablespace. Plutôt que d'ajouter le numéro de tablespace dans le ROWID, c'est le DATA_OBJECT_ID (DATAOBJ# ou OBJD ou OBJ ou OBJECT_NUMBER) qui est utilisé. Il s'agit de l'identifiant de l'objet physique, c'est à dire du segment, contrairement à l'OBJECT_ID (OBJ# ou OBJN) qui est l'identifiant de l'objet logique. Le DATA_OBJECT_ID permet d'identifier le tablespace grâce au dictionnaire, puisque un segment se trouve dans un et un seul tablespace.
Ainsi, le ROWID ne comprends que des informations physiques pour identifier le bloc (segment, datafile, block). C'est ce qui rend optimal les tablespaces transportables ainsi que l'échange de partitions, car ils n'ont pas à modifier le contenu des blocs mais seulement les méta-données du dictionnaire.
L'ancien ROWID est appelé le Restricted ROWID, il est affiché sous la forme block#.row#.file# et celui qui inclut le data_objet_id est appelé Extended ROWID, il est affiché encodé (6 caractères pour dataobj#, 9 caractères pour file#/block#, 3 caractères pour row#). Cet article de Jonathan Lewis explique la taille nécessaire au stockage du ROWID dans différents cas, ce qui peut être utile pour estimer la taille d'un index par exemple.
Dans une récente discussion sur le blog un article de Charles Hooper , j'ai fait un commentaire disant qu'il est difficile d'être précis et non-ambigu lorsqu'on estime l'espace nécessaire au stockage du ROWID. Je vais donc essayer d'énumérer tous les cas possible que l'on peut rencontrer. Franchement, je ne suis pas sûr d'être exhaustif dès le premier jet.
Alors, quelle place prend un ROWID ?
Vous devez être identifié pour poster un commentaire.
, Pachot Franck Cet article est la traduction d'un article de Jonathan Lewis publié sur son blog. L'article original en anglais se trouve ici.
J'ai traduit récemment un article de Doug Burns sur un concept très important lorsqu'on étudie les performances d'un système: améliorer le temps de réponse d'un traitement individuel, et améliorer le débit (throughput) d'un ensemble de traitement sont 2 objectifs différents, et souvent contradictoires.
Doug Burns donnait un exemple concret en différenciant la mesure du temps de réponse d'une session individuelle (response time) et la mesure du débit d'une charge globale (throughput). Jonathan Lewis montre ici de manière simple la théorie qu'il y a derrière. Pour aller plus loin dans la théorie, je traduirais prochainement les commentaires de Cary Millsap là dessus.
Je n'ai pas l'intention de rentrer dans la technique des files d'attentes (Queuing Theory) qui est plutôt le domaine de Cary Millsap, mais je voudrais juste donner un exemple pour montrer de quelle manière la théorie des files d'attentes (Queues) s'applique à Oracle, en répondant à la question suivante que m'a posé un client récemment:
"Comment peuvent-ils se plaindre que le temps de réponse a empiré, alors que le débit (throughput) global a augmenté de 5% ?"
La réponse malheureusement est: oui, bien sûr, le temps de réponse est peut-être pire et ceci vient justement du fait que le débit est meilleur, et je vais donner un exemple dans cette note, construit pour montrer comment cela peut se produire.
Vous devez être identifié pour poster un commentaire.
, Pachot Franck Cet article est la traduction d'un article de Jonathan Lewis publié sur son blog. L'article original en anglais se trouve ici.
Il montre un fonctionnalité peu connue: la compression des données transférées par SQL*Net lorsque il y a répétition de valeurs d'une ligne à l'autre. Et l'avantage de récupérer ces données triées sur ces colonnes répétitives.
Voici une petite démonstration que j'avais l'intention d'écrire depuis ces dernières années.
C'est très simple: je crée une table, et je l'interroge plusieurs fois.
Vous devez être identifié pour poster un commentaire.
, Pachot Franck Cet article est la traduction d'un article de Jonathan Lewis publié sur son blog. L'article original en anglais se trouve ici.
Il précise la signification des colonnes WAIT_TIME et SECONDS_IN_WAIT dans V$SESSION et V$SESSION_WAIT, en fonction de la colonne STATE
Ces vues donnent un moyen rapide pour diagnostiquer une session qui semble bloquée, et savoir si elle est en attente d'un appel système (wait events) ou en CPU.
Un post récent sur le forum OTN fait le commentaire suivant: “le wait event est: latch shared pool, et la CPU est à 100%, il tourne depuis quelques heures et semble bloqué...”
Cela me rappelle une erreur commise fréquemment lorsque les gens regardent la vue V$SESSION_WAIT s'ils oublient de regarder la valeur de la colonne STATE.
Ce que vous devriez vérifier se trouve dans la requête suivante:
select sid, state, event, wait_time, seconds_in_wait from v$session_wait
Lorsque vous interprétez le résultat, souvenez-vous que la session n'est en train d'attendre que si la colonne STATE est exactement à 'WAITING'.
Sinon, c'est que la session est en CPU (ou pour être plus précis techniquement, dans la runqueue) et n'est pas en train d'attendre sur un wait event.
Si STATE montre autre chose que 'WAITING', alors la différence entre SECONDS_IN_WAIT et WAIT_TIME donne approximativement (à 3 secondes près puisque la valeur est mise à jour à peu près toutes les 3 secondes) le temps deuis lequel la session est en CPU, ou plus précisément dans la runqueue, depuis la fin du dernier wait event.
A noter: cela vous montre que cette colonne SECONDS_IN_WAIT est très mal nommée, et devrait plutôt être appelée
'nombre_de_secondes_depuis_le_debut_du_dernier_wait_avec_une_erreur_jusqua_trois_secondes', mais il y a une limite de 32 caractères pour les noms de colonnes.
A noter aussi que depuis la 10g, on peut aussi faire cette requête sur V$SESSION au lieu de V$SESSION_WAIT
Vous devez être identifié pour poster un commentaire.
, Pachot Franck Cet article est la traduction d'un article de Jonathan Lewis. L'article original en anglais se trouve ici. J'ai cependant traduit l'exemple de requête dans une syntaxe Oracle, et l'idée d'index cluster de SQL Server correspond à celle d'IOT sous Oracle.
Jonathan Lewis décrit ici une démarche visuelle pour comprendre une requête SQL en faisant un schéma des tables impliquées.
C'est parfois intéressant de s'éloigner du clavier lorsqu'on se bat avec une requête peu performante et assez complexe, et de prendre un papier et un crayon à la place. En faisant un schéma qui montre les tables impliquées, les jointures, les volumes de données manipulées, et les indexes, vous pourrez comparer plus facilement l'efficacité des différents chemins d'exécution que la requête peut prendre pour passer d'une table à une autre.
Vous devez être identifié pour poster un commentaire.
Traduction en français d'articles d'experts a propos des concepts avancés d'Oracle.
Traduits par Franck Pachot
contact@pachot.net
| Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
Copyright © 2000-2012 - www.developpez.com