J'ai une requête paramétrée. Selon les valeurs des paramètres, le plan de requête optimal varie de manière significative. Voici le problème: Oracle utilise le plan à partir de l'invocation de la première requête pour les invocations ultérieures entraînant de mauvaises performances. Je m'occupe de ça par SQL dynamique mais cette façon est loin d'être élégante. La question est donc la suivante: existe-t-il un moyen de dire à Oracle que le plan de requête doit être recalculé?Existe-t-il un moyen de demander à Oracle de recalculer un plan de requête pour chaque appel de requête?
Répondre
Pour Oracle 10g nous choisirions une table dans la requête et exécuter
GRANT SELECT ON table1 TO user1;
perdriez le plan d'une requête faisant référence à cette table. Bien sûr, vous voudriez choisir une table qui a un impact minimal sur les autres requêtes. Voir aussi this page pour plus d'informations et un exemple de liste.
Si le plan de requête change vraiment de manière significative sur la valeur du paramètre, vous ne devriez peut-être pas utiliser de variables de liaison pour ce paramètre.
Combien de valeurs différentes ce paramètre peut-il prendre? S'il n'y en a que quelques-uns, vous obtiendrez un ou deux plans de requête (un pour chaque valeur), et ceux-ci, espérons-le, fonctionneront bien et pourront être réutilisés. Vous pouvez également utiliser les commentaires "/ * C'EST LA VALEUR BRACKET UN * /" dans l'instruction SQL pour les séparer (ou interroger les indicateurs de l'analyseur, si vous pensez que vous savez lesquels sont appropriés, quelque chose comme/* + CARDINALITY */pourrait s'appliquer ici).
De toute façon, je pense que vous voulez avoir des instructions SQL séparées afin que vous puissiez obtenir des rapports séparés dans Statspack et vos amis, car il semble que vous vouliez affiner cette requête.
Si vous voulez vraiment générer un nouveau plan d'interrogation à chaque fois, vient de mettre un commentaire unique comme le suggère Thilo
select /* SQLID=1234 */ 1 from dual;
select /* SQLID=1235 */ 1 from dual;
Ceux-ci devraient générer des plans uniques. Je voudrais être très méfiant de la nécessité de faire cela, cependant, avant d'essayer de contourner l'optimiseur, vous devriez être très sûr que vos statistiques ne sont pas fausses.
L'optimiseur utilise notamment des histogrammes sur les colonnes associées. Si vous utilisez une variable de liaison et si vous avez des histogrammes dans la colonne correspondante, le plan peut changer en fonction de la valeur du paramètre. Ce premier plan restera dans le pool partagé et sera utilisé pour toutes les valeurs.
Si vous ne le souhaitez pas, vous pouvez utiliser des littéraux au lieu de binds (si vous n'avez pas trop de versions du même sql). Ou vous pouvez supprimer l'histogramme, en supprimant l'histogramme assure que indépendant de la valeur du paramètre de liaison le même plan sera généré. Invalider le sql pour chaque exécution n'est pas une bonne idée. En fonction de la fréquence d'utilisation de ce sql, de nouveaux problèmes peuvent survenir, tels que les problèmes de verrouillage causés par l'analyse syntaxique.
Existe-t-il un moyen de dire à Oracle que le plan de requête doit être recalculé?
Vous pouvez créer plusieurs OUTLINE
« s pour les différents plans d'exécution et sélectionner celui à utiliser à l'aide OUTLINE CATEGORIES
:
CREATE OUTLINE ol_use_nl
FOR
SELECT *
FROM mytable1 mt1
JOIN mytable2 mt2
ON mt1.id = mt2.id
WHERE mt1.value BETWEEN :a AND :b
CATEGORY FILTERED;
/* Edit the outline to add USE_NL */
CREATE OUTLINE ol_use_nl
FOR
SELECT *
FROM mytable1 mt1
JOIN mytable2 mt2
ON mt1.id = mt2.id
WHERE mt1.value BETWEEN :a AND :b
CATEGORY UNFILTERED;
/* Edit the outline to add USE_HASH */
ALTER SESSION SET USE_STORED_OUTLINES = FILTERED;
SELECT *
FROM mytable1 mt1
JOIN mytable2 mt2
ON mt1.id = mt2.id
WHERE mt1.value BETWEEN 1 AND 2
/* This will use NESTED LOOPS */
ALTER SESSION SET USE_STORED_OUTLINES = UNFILTERED;
SELECT *
FROM mytable1 mt1
JOIN mytable2 mt2
ON mt1.id = mt2.id
WHERE mt1.value BETWEEN 1 AND 1000000
/* This will use HASH JOIN */
Votre problème est dû à lier la variable Peeking - le mettre hors tension pour la base de données entière serait probablement casser d'autres choses, mais vous pouvez la désactiver pour seulement cette requête en ajoutant l'indication suivante:
/* + opt_param (« _ OPTIM_PEEK_USER_BINDS », FAUX) */
Il veut probablement le contraire, "coup d'oeil à chaque fois". Je me demande s'il y a un indice pour cela aussi. – Thilo
"Peek Every Time" est d'utiliser des littéraux. –
L'OP nous dit qu'il ne peut pas modifier les instructions sql. Avec l'utilisation du paquet dbms_advanced_rewrite
, il est possible d'intercepter une instruction SQL et de modifier cette instruction SQL.
- 1. Formatage de requête Oracle DB
- 2. Requête django db à chaque requête
- 3. Oracle - délai de requête OCI
- 4. Question de requête SQL Oracle
- 5. Oracle - procédure de requête concernant
- 6. Oracle optimisation de calcul de la date de requête impliquant
- 7. Limiter l'heure de requête Oracle/ASPX
- 8. Requête pour un formulaire de recherche
- 9. Modifier un attribut pour chaque objet dans un ensemble de requête
- 10. Appel d'une requête Oracle paramétrée depuis ADODB dans Classic ASP
- 11. Comment créer un répertoire de système de fichiers dans un appel/requête SQL Server 2005
- 12. Requête SQL pour Top 5 de chaque catégorie
- 13. L'ajout de conditions de jointure redudant dans Oracle aboutit à un plan différent
- 14. Oracle gauche requête de jointure externe
- 15. Connexion Oracle/délai d'expiration de la requête
- 16. SQL Server - Plan d'exécution de requête pour les instructions conditionnelles
- 17. Ajouter un en-tête à chaque requête en utilisant .htaccess
- 18. oracle -left requête de jointure externe ANSI
- 19. Sélectionnez un échantillon aléatoire de résultats d'un résultat de requête
- 20. Un moyen d'améliorer cette requête lente?
- 21. Un moyen d'optimiser cette requête mysql?
- 22. Constructeur du contrôleur appelé à chaque requête
- 23. Appel d'une fonction Oracle à partir de C#
- 24. requête de requête linq à sql
- 25. Requête SQL pour un schéma de base de données
- 26. requête Django pour un grand nombre de relations
- 27. requête spool oracle
- 28. Un service Web .NET instancié avec chaque appel de méthode?
- 29. Passer un appel de service Web SOAP à l'aide d'une requête Web
- 30. Aidez-nous à optimiser une requête Oracle?
Je ne peux pas modifier la source SQL. Les statistiques sont bonnes. Dans mon cas, le problème est que le plan de requête est obsolète et mauvais. Si j'invalide le plan, Oracle calculera un nouveau bon plan. –
Il-Bhima est le chemin à parcourir alors si vous ne pouvez pas changer la source SQL du tout. –