2010-08-24 10 views
5

Dans ma base de données à plusieurs endroits, les développeurs ont utilisé SQL dynamique au lieu de statique. Et ils disent que la raison en est d'améliorer la performance. Quelqu'un peut-il me dire si possible SQL dynamique peut vraiment augmenter les performances dans la procédure stockée ou bloc plsql?Statique vs dynamique SQL

Qui va s'exécuter plus vite et pourquoi?
1.

begin 
    execute immediate 'delete from X'; 
end; 

2.

begin 
    delete from X; 
end; 
+2

http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/ad/c0005785.htm – DumbCoder

+0

Je ne suis pas sûr de des requêtes comme 'supprimer de X', mais en général si votre requête a des paramètres, la requête dynamique peut fonctionner plus rapidement, je l'ai vu beaucoup de fois. Pourquoi? Il semble que lorsque vous compilez votre base de données sproc, vous ne savez pas quels sont les paramètres et vous pouvez sélectionner un mauvais plan. En cas de requête dynamique, lorsque je crée une chaîne avec une requête et que je l'exécute, tous les paramètres sont insérés et le plan d'exécution est meilleur. Cela peut sembler étrange, mais quand la performance compte, je le fais aussi. Retour à votre question -> vos requêtes sont-elles écrites, ou sont-elles plus complexes (avec des paramètres insérés par sproc)? – Maxym

+0

La plupart des requêtes sont simples et peuvent être écrites de manière statique. C'est pourquoi je me demandais pourquoi opter pour une requête dynamique quand elle peut être écrite de manière statique. –

Répondre

12

Votre exemple de code est si simple qu'il y aura peu de différence, mais dans ce cas la version statique s'exécutera probablement mieux. La principale raison d'utiliser le SQL dynamique pour les performances est lorsque l'instruction SQL peut varier de manière significative - par exemple, vous pouvez ajouter du code supplémentaire à la clause WHERE au moment de l'exécution en fonction de l'état du système (restreindre par une sous-requête sur l'adresse, si l'adresse est entrée, etc.).

Une autre raison est que parfois l'utilisation de variables Bind comme paramètres peut être contre-productive. Un exemple est si vous avez quelque chose comme un champ d'état, où les données ne sont pas distribuées uniformément (mais sont indexées).

Tenir compte des 3 énoncés suivants, lorsque 95% des données est « P'rocessed

SELECT col FROM table 
    WHERE status = 'U'-- unprocessed 
    AND company = :company 

    SELECT col FROM table 
    WHERE status = 'P' -- processed 
    AND company = :company 

    SELECT col FROM table 
    WHERE status = :status 
    AND company = :company 

Dans la version finale, Oracle choisira un plan générique expliquer. Dans la première version, il peut décider que le meilleur plan est de commencer par l'index sur le statut (sachant que 'les entrées U-traitées sont une très petite partie du total).

Vous pouvez implémenter cela à travers différentes instructions statiques, mais lorsque vous avez des instructions plus complexes qui ne changent que de quelques caractères, le SQL dynamique peut être une meilleure option.

Downsides

Chaque répétition de la même instruction SQL dynamique encourt une analyse syntaxique douce, qui est une petite tête par rapport à une déclaration statique, mais encore une surcharge.

Chaque nouvelle instruction sql (dynamique ou statique) entraîne également un verrou sur le SGA (mémoire partagée) et peut entraîner le rejet d'instructions «anciennes».

Une conception de système mauvaise, mais courante, consiste à ce que quelqu'un utilise le SQL dynamique pour générer des sélections simples qui ne varient que par la clé - c'est-à-dire.Les instructions individuelles seront rapides, mais les performances globales du système se détérioreront, car elles détruisent les ressources partagées.

En outre, il est beaucoup plus difficile d'intercepter les erreurs lors de la compilation avec SQL dynamique. Si vous utilisez PL/SQL, vous perdez un bon temps de compilation. Même en utilisant quelque chose comme JDBC (où vous déplacez tout le code de votre base de données dans des chaînes - bonne idée!) Vous pouvez obtenir des pré-analyseurs pour valider le contenu JDBC. SQL dynamique = test d'exécution uniquement.

Transparents

Les frais généraux d'exécution immédiate est faible - il est dans les millièmes de seconde - cependant, il peut ajouter si cela est dans une boucle/sur une méthode appelée une fois par objet/etc J'ai une fois obtenu une amélioration de la vitesse de 10x en remplaçant SQL dynamique avec SQL statique généré. Cependant, cela a compliqué le code, et n'a été fait que parce que nous avions besoin de la vitesse.

+1

JulesLt a de bons points dans sa réponse et fait allusion à quelque chose à discuter des frais généraux qui doit être dit explicitement - mettre de côté les considérations variables, l'analyse, etc., EXECUTER IMMEDIATE dans un bloc PL/SQL aura toujours un désavantage sur un PL équivalent/Appel SQL car l'exécution impliquera un changement de contexte vers le moteur SQL. – dpbradley

0

Malheureusement, cela ne varie au cas par cas.

Pour vos exemples donnés, il n'y a probablement pas de différence mesurable. Mais pour un exemple plus compliqué, vous voudrez probablement tester votre propre code.

Le lien @DumbCoder donné dans les commentaires a d'excellentes règles empiriques qui s'appliquent également à Oracle pour la plupart. Vous pouvez utiliser quelque chose comme ça pour vous aider à décider, mais il n'y a pas de règle simple comme «dynamique est plus rapide que statique».