Sur Oracle 10gr2, j'ai plusieurs requêtes SQL que je compare les performances, mais après la première exécution, la table v $ sql a le plan d'exécution stocké pour la mise en cache, donc pour l'une des requêtes, je passe de 28 secondes lors de la première exécution à 0,5. quelques secondes après.
J'ai essayé
ALTER SYSTEM FLUSH BUFFER_CACHE; - après avoir exécuté cela, la requête s'exécute régulièrement à 5 secondes, ce qui, à mon avis, n'est pas exact.
pensé peut-être supprimer l'élément de ligne lui-même du cache: supprimer de v $ sql où sql_text comme 'select * from .... mais obtient une erreur de ne pas pouvoir supprimer de la vue.
Peter vous a donné la réponse à la question que vous avez posée.
alter system flush shared_pool;
C'est l'instruction que vous utiliseriez pour "supprimer les instructions préparées du cache".
(Les instructions préparées ne sont pas les seuls objets vidés du pool partagé, l'instruction fait plus que cela.)
Comme je l'ai indiqué dans mon commentaire précédent (sur votre question), v$sql
n'est pas une table. C'est une vue dynamique des performances, une représentation pratique sous forme de tableau des structures de mémoire interne d'Oracle. Vous ne disposez que du privilège SELECT sur les vues de performances dynamiques, vous ne pouvez pas en supprimer des lignes.
Vider le pool partagé et le cache de tampon?
Ce qui suit ne répond pas directement à votre question. Au lieu de cela, il répond à une question fondamentalement différente (et peut-être plus importante):
Doit-on normalement vider le pool partagé et/ou le cache de tampon pour mesurer les performances d'une requête?
Bref, la réponse est non.
Je pense que Tom Kyte répond assez bien à cela:
http://www.Oracle.com/technology/oramag/Oracle/03-jul/o43asktom.html
http://www.Oracle.com/technetwork/issue-archive/o43asktom-094944.html
<excerpt>
En fait, il est important qu'un outil de réglage ne fasse pas cela. Il est important d'exécuter le test, d'ignorer les résultats, puis de l'exécuter deux ou trois fois et de faire la moyenne de ces résultats. Dans le monde réel, le cache tampon ne sera jamais dénué de résultats. Jamais. Lorsque vous accordez, votre objectif est de réduire les E/S logiques (LIO), car alors les E/S physiques (PIO) prendront soin de elles-mêmes.
Considérez ceci: vider le pool partagé et le cache de tampon est encore plus artificiel que de ne pas les vider. La plupart des gens semblent sceptiques à ce sujet, je suppose, car cela va à l'encontre de la sagesse conventionnelle. Je vais vous montrer comment procéder, mais pas pour que vous puissiez l'utiliser pour les tests. Je vais plutôt l'utiliser pour démontrer pourquoi c'est un exercice futile et totalement artificiel (et conduit donc à de fausses hypothèses). Je viens de démarrer mon PC et j'ai exécuté cette requête sur une grande table. Je "vide" le cache tampon et le réexécute:
</excerpt>
Je pense que Tom Kyte a parfaitement raison. En termes de résolution du problème de performances, je ne pense pas que "vider le cache du plan d'exécution Oracle" soit normalement une étape pour une analyse comparative fiable.
Répondons à la préoccupation concernant les performances.
Vous nous dites que vous avez observé que la première exécution d'une requête prend beaucoup plus de temps (~ 28 secondes) par rapport aux exécutions suivantes (~ 5 secondes), même lors du vidage (tous les blocs d'index et de données de) du cache de tampon.
Pour moi, cela suggère que l'analyse dure fait un gros travail. C'est soit beaucoup de travail, soit sa rencontre avec beaucoup d'attente. Cela peut être étudié et réglé.
Je me demande si les statistiques sont peut-être inexistantes et l'optimiseur passe beaucoup de temps à collecter des statistiques avant de préparer un plan de requête. C'est l'une des premières choses que je vérifierais, que les statistiques sont collectées sur toutes les tables référencées, les index et les colonnes indexées.
Si votre requête rejoint un grand nombre de tables, le CBO peut envisager un grand nombre de permutations pour l'ordre de jointure.
Une discussion sur le traçage Oracle dépasse le cadre de cette réponse, mais c'est la prochaine étape.
Je pense que vous allez probablement vouloir retracer les événements 10053 et 10046.
Voici un lien vers une discussion sur "l'événement 10053" par Tom Kyte qui peut vous être utile:
http://asktom.Oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:63445044804318
histoire anecdotique liée tangentiellement concernant les performances de l'analyse dure
Il y a quelques années, j'ai vu une requête qui s'était écoulée en termes de MINUTES lors de la première exécution, les exécutions suivantes en termes de secondes. Ce que nous avons constaté, c'est que la grande majorité du temps pour la première exécution a été consacrée à l'analyse approfondie.
Cette requête de problème a été écrite par un développeur CrystalReports qui a innocemment (naïvement?) Rejoint deux vues de rapport énormes.
L'une des vues était une jointure de 62 tables, l'autre vue était une jointure de 42 tables.
La requête a utilisé l'optimiseur basé sur les coûts. Le traçage a révélé qu'il ne s'agissait pas d'un temps d'attente, mais de tout le temps processeur consacré à l'évaluation des chemins de jointure possibles.
Chacun des fournisseurs a fourni des vues de "rapport" n'était pas trop mal en soi, mais lorsque deux d'entre eux ont été joints, c'était terriblement lent. Je crois que le problème était le grand nombre de permutations de jointure que l'optimiseur envisageait. Il existe un paramètre d'instance qui limite le nombre de permutations prises en compte par l'optimiseur, mais notre correctif consistait à réécrire la requête. La requête améliorée n'a joint que la douzaine de tables réellement nécessaires à la requête.
(Le correctif immédiat immédiat à court terme était de planifier une exécution de la requête plus tôt le matin, avant l'exécution de la tâche de génération de rapport. Cela a rendu la génération de rapport "plus rapide", car la génération de rapport a utilisé le déjà déclaration préparée dans le pool partagé, en évitant l'analyse approfondie.
Le correctif de pansement n'était pas une vraie solution, il a simplement déplacé le problème vers une exécution préliminaire de la requête, lorsque le long temps d'exécution n'a pas été remarqué.
Notre prochaine étape aurait probablement été d'implémenter un "plan stocké" pour la requête, afin d'obtenir un plan de requête stable.
Bien sûr, la réutilisation des instructions (éviter l'analyse approfondie, en utilisant des variables de liaison) est le modèle normatif dans Oracle. Il améliore les performances, l'évolutivité, yada, yada, yada.
Cet incident anecdotique peut être entièrement différent du problème que vous observez.
HTH
Cela fait un moment que je n'ai pas travaillé avec Oracle, mais je pense que les plans d'exécution sont mis en cache dans le pool partagé. Essaye ça:
alter system flush shared_pool;
Le cache de tampon est l'endroit où Oracle stocke les derniers fichiers utilisés data afin de minimiser l'io du disque.
Nous avons beaucoup travaillé ces derniers temps avec les requêtes d'optimisation des performances, et l'un des coupables des performances de requête incohérentes est le cache du système de fichiers sur lequel Oracle est assis.
Il est possible que pendant que vous videz le cache Oracle, le système de fichiers contienne toujours les données que votre requête demande, ce qui signifie que la requête sera toujours renvoyée rapidement.
Malheureusement, je ne sais pas comment vider le cache du système de fichiers - j'utilise simplement un script très utile de nos administrateurs système très utiles.