Fonctionnalités Objet-Relationnel d’Oracle, par Tom Kyte

Cet article est la traduction d’une réponse Tom Kyte à des questions sur les fonctionnalités Objet-Relationnel d’Oracle
(L’article original en anglais se trouve sur AskTom ici).

Tom Kyte donne son avis sur l’utilisation de ces fonctionnalités (Tables Relationnelles, vues Objet-Relationnel, Tables Objet-Relationnel)

Question:

Bonjour Tom,

J’ai quelques questions sur les fonctionnalités Objet-Relationnel d’Oracle.

J’ai la structure suivante:
Lire la suite

Ecritures coh̩rentes Рcons̩quences pour le d̩veloppeur, par Tom Kyte (3̬me partie)

Cet article est la traduction d’un article de Tom Kyte sur son blog (L’article original en anglais se trouve ici).
Lectures cohérentes et multi-versionnage, par Tom Kyte


Il est conseillé lire préalablement les premières partie:

La première chose qui vient à l’esprit, c’est que le trigger se déclenche deux fois. On avait une table avec une seule ligne, et un trigger BEFORE FOR EACH ROW qui se déclanche pour chaque ligne. Un a fait un update sur une seule ligne et le trigger s’est déclanché deux fois.

Vous devez penser aux conséquentes de cela. Si vous faites dans votre trigger quoi que ce soit qui ne soit pas transactionnel, vous pouvez avoir un problème assez sérieux.
Lire la suite

Ecritures cohérentes – observation d’un redémarrage, par Tom Kyte (2ème partie)

Cet article est la traduction d’un article de Tom Kyte sur son blog (L’article original en anglais se trouve ici).


Il est conseillé lire préalablement la première partie:

Voir un redémarrage d’une requête update est plus plus facile qu’on ne pense.
En fait, nous allons même en voir un avec une simple table d’une seule ligne.
Lire la suite

Ecritures cohérentes, par Tom Kyte (1ère partie)

Cet article est la traduction d’un article de Tom Kyte sur son blog (L’article original en anglais se trouve ici). L’article est en 3 parties (il s’agit ici de la partie 1) et il est extrait de son livre Expert Oracle Database Architecture.

Il peut être utile de (re)lire avant:

Nous avons étudié précédemment (en français ici) la lecture cohérente: la capacité d’Oracle à utiliser les informations d’undo pour fournir des requêtes non-bloquantes et cohérentes (c’est à dire correctes) pour une lecture. Nous savons que lorsque Oracle lit des blocs pour notre requête, dans le buffer cache, il s’assure que la version du bloc est assez ‘vieille’ pour que notre requête puisse le voir.

Mais cela soulève la question suivante: Qu’en est-il des écritures/modifications ? Qu’est-ce qui se passe lorsque vous exécutez l’instruction UPDATE suivante: UPDATE T SET X = 2 WHERE Y = 5;
et que, pendant que cette requête est en cours d’exécution, quelqu’un modifie une ligne en faisant passer la valeur de Y de 5 vers 6, et commite cette modification, avant que nôtre requête n’ait lu cette ligne ?

Autrement dit, lorsque votre mise à jour a commencé, certaines lignes ont Y=5. Et comme votre mise à jour fait des lectures cohérentes, elle voit pour cette ligne Y=5, puisque c’est la valeur qu’il y avait au moment où votre update a démarré. Cependant, la valeur actuelle de Y est maintenant 6, et non plus 5, et avant de mettre à jour la valeur de X, Oracle va vérifier si la valeur de Y est toujours 5. Maintenant que doit-il se passer ? Et comment cela impacte les update ?

De toute évidence, nous ne pouvons pas modifier une ancienne version d’un bloc: quand on va modifier une ligne, il faut modifier la version actuelle du bloc. En outre, Oracle ne peut pas simplement ignorer cette ligne, car ce serait une lecture incohérente et imprévisible. Ce que nous allons découvrir, c’est que dans ce cas, Oracle va redémarrer à zéro l’écriture des modification.
Lire la suite

Verrous et signification du mode (lock mode), par Jonathan Lewis

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.

Lire la suite

Le ROWID et la place qu’il prend, par Jonathan Lewis

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 ?
Lire la suite

Les principes fondamentaux d’un datawarehouse – Le Partitionnement, par Greg Rahn

Cet article est la traduction d’un article de Greg Rahn publié sur son blog. L’article original en anglais est:The Core Performance Fundamentals Of Oracle Data Warehousing – Partitioning. Cet article fait partie d’une série sur les principes fondamentaux des datawarehouse.

Le partitionnement est une fonctionnalité majeure pour les performance d’un datawarehouse sous Oracle, car l’élagage des partition (partition pruning) va la plupart du temps faire en sorte qu’il y ait moins de données à lire sur une table. Le résultat, c’est qu’il y a besoin de moins de ressources système, et que les requêtes sont plus performantes.
Quelqu’un m’a dit un jour « les I/O les plus rapides sont ceux que l’on ne fait jamais » C’est précisément la raison pour laquelle le partitionnement est ce qu’il y a de mieux pour un datawarehouse: il permet de réduire les I/O.
Je parle souvent de l’élagage des partitions (partition pruning) comme d’un anti-index. Un index est utilisé pour trouver la faible quantité de données qui est nécessaire, alors que le partitionnement est utilisé pour éliminer une grande quantité de données qui n’est pas nécessaire.

Principales utilisations du partitionnement

Je vois quatre raisons pour l’utilisation du partitionnement dans un datawarehouse Oracle:

  • Élimination de données
  • Jointures partition par partition (Partition-Wise Joins)
  • Maintenabilité (chargements par échange de partitions, indexes locaux, etc.)
  • Cycle de vie des données (Information Lifecycle Management – ILM)

Lire la suite

Performance: Temps de réponse vs. Débit, par Cary Millsap

Cet article est la traduction d’un article de Cary Millsap publié sur son blog. L’article original en anglais est:Throughput versus Response Time. C’est un commentaire sur l’article de Doug Burns Time Matters: Throughput vs. Response Time. Cary Millsap est un spécialiste de la performance, du tuning Oracle et a beaucoup écrit sur les files d’attentes.

J’ai apprécié le post de Doug Burns Performance: Mesurer le temps de réponse ou le débit sur son blog. Si vous ne l’avez pas encore lu, vous devriez. L’article et les commentaires sont excellents.
La courbe de rendement (temps de réponse en fonction de la charge du système) fait un coude, au point où le temps de réponse, presque constant, devient tout d’un coup exponentiel lorsque le système atteint une certaine charge.

Exemple de courbe de rendement tiré de Optimizing Oracle performance
– En abscisse (ρ): la charge (ou utilisation),
РEn ordonn̩e (R): le temps de r̩ponse.
– Les 3 courbes correspondent à un degré de parallélisme de 1,2 et 8

Courbe charge/temps de réponse

Le ‘coude’ (‘knee‘), est le point correspondant à la charge pour laquelle le rapport temps de réponse / utilisation est minimal.
Il peut être déterminé aussi par la tangente à la courbe, passant par le point d’origine des axes.
Ce ‘coude’ se décale vers la droite lorsque le degré de parallélisme augmente.

Lire la suite

Temps passé en file d’attente, par Jonathan Lewis.

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.
Lire la suite

Performance: Mesurer le temps de réponse ou le débit, par Doug Burns

Cet article est la traduction d’un article de Doug Burns publié sur son blog. L’article original en anglais se trouve ici.

C’est une réflexion sur la principale métrique de performance: le temps de réponse, ou le débit (nombre de transaction par unité de temps) en fonction de ce qui est étudié: requête d’une session individuelle, ou charge globale d’un système (workload).

J’ai été incité à écrire cet article a la suite du commentaire suivant que Niall Litchfield a fait dans un email:
« … Je remarque qu’une fois qu’on commence à définir une charge globale de travail (workload), ou un ensemble de transactions, dans des termes métier (du genre ‘j’ai besoin d’effectuer toutes ces choses, qu’est-ce qui marche le mieux ?’) alors le temps de réponse de la charge de travail complète * a un sens, d’une part comme métrique, mais surtout comme un objectif de tuning. J’ai l’impression que depuis ces 10 dernières années, les discussions sur les performances se font autour des requêtes, ou de l’optimisation d’une session, en supposant que si on améliore les performances d’une requête particulière, alors on va aussi améliorer la charge de travail complète, telle que le voit le métier. C’est souvent vrai, mais c’est souvent faux aussi. Les mesures de performances seront toujours basées sur le temps de réponse, mais il pourrait y avoir des d’autres méthodes de tuning. Ça pourrait être aussi simple que de définir la première étape du tuning comme ‘Définir la charge de travail (workload) la plus importante important pour le métier’ au lieu de ‘définir la tâche importante pour le métier’

Je suis d’accord avec Niall, particulièrement sur le fait actuellement on met plus l’accent sur l’optimisation de sessions individuelles, ou des requêtes isolées, plutôt que l’optimisation de la charge de travail globale.

Je vais dire cela d’une autre manière: si vous essayez d’avoir le meilleur débit pour toute la charge de travail (workload throughput) alors l’objectif le plus important n’est peut être pas le meilleur temps de réponse d’une session individuelle.C’est pourquoi j’ai quelques slides d’un cours que j’ai écris auparavant pour Oracle et qui définissent plusieurs façons d’évaluer les performances du système, incluant:

  • le temps de réponse (response time)
  • le débit (throughput)
  • et l’évolutivité (scalability)

Lire la suite