IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Administration Oracle Discussion :

cursors, soft parse, hard parse -> static sql


Sujet :

Administration Oracle

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    mai 2007
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2007
    Messages : 192
    Points : 392
    Points
    392
    Par défaut cursors, soft parse, hard parse -> static sql
    Bonjour,
    je sais que le titre peut faire peur et on va se demander s'il ne va pas couvrir 1 000 hectares de connaissance...

    Ne vous inquiétez pas, je voudrais juste poser une question sur les "static sql".

    Il me semble qu'au niveau perfs, c'est ce qu'il y a de meilleur (même pas de soft parse (si, non ?)).

    Je voulais savoir s'il y a d'autre moyen que d'utiliser du PL/SQL pour "arriver" à ne faire "qu' " exécuter et ne pas parser un select par exemple.

  2. #2
    Expert éminent
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    novembre 2007
    Messages
    1 813
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : Suisse

    Informations professionnelles :
    Activité : Developer Advocate YugabyteDB
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2007
    Messages : 1 813
    Points : 6 411
    Points
    6 411
    Par défaut
    Oh oui, bien sûr.
    En java par exemple, tu fais un PreparedStatement, avec des variables, puis tu l'exécute autant de fois que tu veux avec des nouvelles valeurs à chaque fois. Et il sera parsé qu'une seule fois.

    Dans tous les langages, c'est possible, heureusement !
    Franck Pachot - Developer Advocate Yugabyte 🚀 Base de Données distribuée, open source, compatible PostgreSQL
    🗣 twitter: @FranckPachot - 📝 blog: blog.pachot.net - 🎧 podcast en français : https://anchor.fm/franckpachot

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    mai 2007
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2007
    Messages : 192
    Points : 392
    Points
    392
    Par défaut ok mais
    lorsque tu dis qu'il ne sera parsé qu'une seule fois, c'est justement là que j'ai cette petite incertitude...

    Il ne sera HARD-PARSÉ qu'une seule fois, c'est bien ça ?
    Par contre, avec des valeurs différentes de binding, on aura bien à chaque fois un SOFT PARSE, non ?

  4. #4
    Expert éminent
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    novembre 2007
    Messages
    1 813
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : Suisse

    Informations professionnelles :
    Activité : Developer Advocate YugabyteDB
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2007
    Messages : 1 813
    Points : 6 411
    Points
    6 411
    Par défaut
    prepareStatement() est l'appel qui parse la requête, et qui retourne un curseur.
    Cela signifie que le curseur a été lu (parsé) syntaxiquement, puis sémantiquement, et ensuite optimisé, pour établir le plan d'exécution.

    Ce parse peut être 'hard' s'il y a tout à faire, ou 'soft' si après la première analyse syntaxique et semantique il apparait comme identique à un SQL déjà optimisé. Ou même pas soft si après analyse syntaxique il est trouvé dans le cache des curseurs de session. Dans tous les cas, c'est un 'parse call'. Qui va être plus ou moins lourd (en latch et en cpu) suivant qu'il est 'hard', 'soft' ou 'session cursor cache hit'

    Alors, chaque appel à execute n'a plus rien à parser: le plan d'exécution déjà établi est appliqué avec les valeurs des variables. Exactement comme un programme déjà compilé.

    Par contre, avec des valeurs différentes de binding, on aura bien à chaque fois un SOFT PARSE, non ?
    Donc non. Pas de parse call du tout. Donc pas de parse ... sauf si entre temps le curseur a été invalidé (pour faire de la place dans le cache ou parce qu'il y a eu du DDL qui remet en cause le plan d'exécution). A ce moment là, pas de parse call (donc pas de 'parse count (total)' incrémenté) mais il y aura un hard parse quand même. Le nom de ces statistiques sont trompeuses. C'est expliqué ici (traduction d'un article de Jonathan Lewis).

    Franck.
    Franck Pachot - Developer Advocate Yugabyte 🚀 Base de Données distribuée, open source, compatible PostgreSQL
    🗣 twitter: @FranckPachot - 📝 blog: blog.pachot.net - 🎧 podcast en français : https://anchor.fm/franckpachot

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    mai 2007
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2007
    Messages : 192
    Points : 392
    Points
    392
    Par défaut merci pachot
    j'avais oublié de fermer ce thread

  6. #6
    Membre éprouvé

    Homme Profil pro
    Inscrit en
    mars 2010
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : mars 2010
    Messages : 512
    Points : 1 298
    Points
    1 298
    Par défaut
    Citation Envoyé par temoanatini Voir le message
    Bonjour,
    je sais que le titre peut faire peur et on va se demander s'il ne va pas couvrir 1 000 hectares de connaissance...

    Je voulais savoir s'il y a d'autre moyen que d'utiliser du PL/SQL pour "arriver" à ne faire "qu' " exécuter et ne pas parser un select par exemple.
    Il existe quand même une possibilité de faire beaucoup de parse et de remplir la shared pool (library cache) même en n'utilisant que du static PL/SQL.

    La question est : savez vous comment ?

    Bien respectueusement

    Mohamed Houri
    Bien Respectueusement
    www.hourim.wordpress.com

    "Ce qui se conçoit bien s'énonce clairement"

  7. #7
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par Mohamed.Houri Voir le message
    Il existe quand même une possibilité de faire beaucoup de parse et de remplir la shared pool (library cache) même en n'utilisant que du static PL/SQL.

    La question est : savez vous comment ?

    ...
    Pour réutiliser un curseur il est nécessaire que le texte de la requête et l’environnement d’optimisation soit identiques.

  8. #8
    Membre éprouvé

    Homme Profil pro
    Inscrit en
    mars 2010
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : mars 2010
    Messages : 512
    Points : 1 298
    Points
    1 298
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Pour réutiliser un curseur il est nécessaire que le texte de la requête et l’environnement d’optimisation soit identiques.
    Bonjour,

    Correct; mais ce n'est pas ceci que je visais.
    La situation est telle que nous n'avons aucun 'stand alone' SQL; nous ne faisons qu'utiliser des procédures PL/SQL stockées qui ne contiennent pas du SQL dynamique mais n'empêche que le select suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select sql_text, executions
    from v$sql
    where executions <= 2;
    retourne beaucoup de records. Il existe trop d'instructions dans le shared pool qui ne sont pas re-executées (qui ne sont pas partagées ''shared'').

    Le but de cette question est uniquement de transmettre le message suivant:
    il ne suffit pas d'utiliser du PL/SQL statique pour être sûr que les bind variables soient correctement utilisées. Il faut aussi être sûr qu'une autre chose
    soit bien utilisée. C'est tout simple mais c'est très important.

    Bien à vous

    Mohamed Houri
    Bien Respectueusement
    www.hourim.wordpress.com

    "Ce qui se conçoit bien s'énonce clairement"

  9. #9
    Membre actif Avatar de Ahmed AANGOUR
    Homme Profil pro
    DBA Oracle
    Inscrit en
    janvier 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : DBA Oracle

    Informations forums :
    Inscription : janvier 2010
    Messages : 139
    Points : 271
    Points
    271
    Par défaut
    Citation Envoyé par pachot Voir le message
    Ou même pas soft si après analyse syntaxique il est trouvé dans le cache des curseurs de session. Dans tous les cas, c'est un 'parse call'. Qui va être plus ou moins lourd (en latch et en cpu) suivant qu'il est 'hard', 'soft' ou 'session cursor cache hit'
    Tom Kyte appelle les 'session cursor cache hit' des "softer soft parse".
    J'aime bien ce terme...
    A noter que pour qu'un curseur soit placé dans le cache des curseurs fermés, il doit avoir été exécuté 3 fois. Le but étant d'éviter de mettre en cache des curseurs qui ne seront exécutés qu'une seule fois.
    Le nombre de curseur "cachables" dans la UGA est défini par le paramètre d'instance SESSION_CACHED_CURSORS

    Ahmed

  10. #10
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par Ahmed AANGOUR Voir le message
    ...
    A noter que pour qu'un curseur soit placé dans le cache des curseurs fermés, il doit avoir été exécuté 3 fois. Le but étant d'éviter de mettre en cache des curseurs qui ne seront exécutés qu'une seule fois.
    ...
    Je m'imagine que vous allez nous fournir une petite démonstration de ce comportement, n'est pas vrai ?

  11. #11
    Membre actif Avatar de Ahmed AANGOUR
    Homme Profil pro
    DBA Oracle
    Inscrit en
    janvier 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : DBA Oracle

    Informations forums :
    Inscription : janvier 2010
    Messages : 139
    Points : 271
    Points
    271
    Par défaut
    Christian Antognini l'explique très bien dans son livre au chapitre 8.

    Mais je viens de faire un petit test basique pour illustrer mon propos:

    Dans Session 1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SQL> select sid from v$mystat where rownum=1;
     
           SID
    ----------
           136
    Depuis Session 2 je regarde les stats existantes pour cette session au niveau de 'session cursor cache hits', ' session cursor cache count' et 'parse count (total)':
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    SQL> SELECT sn.name, ss.value
      2   FROM v$statname sn, v$sesstat ss
      3   WHERE sn.statistic# = ss.statistic#
      4   AND sn.name IN ('session cursor cache hits',
      5   'session cursor cache count',
      6   'parse count (total)')
      7   AND ss.sid =136;
     
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    session cursor cache hits                                                 0
    session cursor cache count                                               18
    parse count (total)                                                      29
    Le nombre de curseurs dans le cache de ma session est de 18 et aucun parse call n'a pour l'instant profité du cache des curseurs (cf. 'session cursor cache hits' ).

    J'exécute une simple requête dans ma 1ère session:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SQL> select count(1) from t1;
     
      COUNT(1)
    ----------
           100
    Je regarde les stats:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SQL> /
     
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    session cursor cache hits                                                 0
    session cursor cache count                                               18
    parse count (total)                                                      31
    Seuls le nombre de 'parse call' a bougé. J'ai toujours les même nombre de curseur dans le cache.

    J'exécute une 2è fois ma requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SQL> select count(1) from t1;
     
      COUNT(1)
    ----------
           100
    les stats:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SQL> /
     
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    session cursor cache hits                                                 0
    session cursor cache count                                               18
    parse count (total)                                                      32
    Idem que pour la 1ère execution.
    J'exécute une 3ème fois:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SQL> /
     
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    session cursor cache hits                                                 0
    session cursor cache count                                               18
    parse count (total)                                                      33
    Idem.

    j'exécute une 4ème fois la même requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SQL> /
     
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    session cursor cache hits                                                 1
    session cursor cache count                                               24
    parse count (total)                                                      34
    cette fois le nombre de curseurs dans le cache a augmenté et surtout mon "session cursor cache hits" est passé à 1. Donc c'est uniquement à la 4ème exécution que le SOFT PARSE est évité au profit d'un softer soft parse.

    Après la 5ème exécution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SQL> /
     
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    session cursor cache hits                                                 2
    session cursor cache count                                               24
    parse count (total)                                                      35
    le "session cursor cache hits" est passé à 2.
    J'ai fait le test pour 10 exécutions et j'obtiens un "session cursor cache hits" de 7.
    10-7 = 3 <=> au nombre d'exécutions nécessaires pour que le curseur soit caché dans la UGA.

  12. #12
    Membre éprouvé

    Homme Profil pro
    Inscrit en
    mars 2010
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : mars 2010
    Messages : 512
    Points : 1 298
    Points
    1 298
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Je m'imagine que vous allez nous fournir une petite démonstration de ce comportement, n'est pas vrai ?
    Trouble shooting performance problem (Christian Antognini) Chapter 8 Parsing
    Server-Side Statement Caching page 326-327-328

    http://books.google.com/books?id=b3D...aching&f=false

    Bien Cordialement

    Mohamed Houri
    Bien Respectueusement
    www.hourim.wordpress.com

    "Ce qui se conçoit bien s'énonce clairement"

  13. #13
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par Ahmed AANGOUR Voir le message
    ...
    Mais je viens de faire un petit test basique pour illustrer mon propos:
    ...
    Merci c'était très bien.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Parse error: parse error, expecting `','' or `';''
    Par rodet dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 03/02/2009, 20h02
  2. [Bénévole] Développeur Soft et Hard pour une association 1901
    Par geobjectif dans le forum Autres
    Réponses: 0
    Dernier message: 02/02/2009, 23h29
  3. Parse error: parse error on line 72
    Par batoule80 dans le forum Langage
    Réponses: 18
    Dernier message: 17/08/2008, 18h40
  4. Réponses: 4
    Dernier message: 25/03/2008, 18h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo