Oracle
 sql >> Base de données >  >> RDS >> Oracle

Procédure stockée Oracle, retour du curseur de référence par rapport aux tableaux associatifs

La demande du DBA n'a pas de sens.

Ce que le DBA pense presque certainement, c'est qu'il veut minimiser le nombre de changements de contexte du moteur SQL vers PL/SQL qui se produisent lorsque vous récupérez des données à partir d'un curseur. Mais la solution suggérée est mal ciblée sur ce problème particulier et introduit d'autres problèmes de performances beaucoup plus graves dans la plupart des systèmes.

Dans Oracle, un changement de contexte SQL vers PL/SQL se produit lorsque la VM PL/SQL demande plus de données à la VM SQL, la VM SQL répond en exécutant davantage l'instruction pour obtenir les données qu'elle empaquette ensuite et restitue au PL /VM SQL. Si le moteur PL/SQL demande des lignes une par une et que vous récupérez un grand nombre de lignes, il est possible que ces changements de contexte représentent une fraction importante de votre temps d'exécution global. Pour lutter contre ce problème, Oracle a introduit le concept d'opérations en masse au moins dans les 8i jours. Cela a permis à la machine virtuelle PL/SQL de demander plusieurs lignes à la fois à la machine virtuelle SQL. Si la machine virtuelle PL/SQL demande 100 lignes à la fois, vous avez éliminé 99 % des changements de contexte et votre code s'exécute potentiellement beaucoup plus rapidement.

Une fois les opérations en masse introduites, il y avait beaucoup de code qui pouvait être refactorisé afin d'être plus efficace en utilisant explicitement BULK COLLECT opérations plutôt que de récupérer ligne par ligne puis d'utiliser FORALL boucles pour traiter les données de ces collections. Au bout de 10,2 jours, cependant, Oracle avait intégré des opérations en masse dans le FOR implicite. boucle donc un FOR implicite loop collecte désormais automatiquement en masse par lots de 100 plutôt que de récupérer ligne par ligne.

Dans votre cas, cependant, puisque vous renvoyez les données à une application cliente, l'utilisation d'opérations en bloc est beaucoup moins importante. Toute API côté client décente aura une fonctionnalité qui permet au client de spécifier le nombre de lignes à extraire du curseur dans chaque aller-retour réseau et ces demandes d'extraction iront directement à la machine virtuelle SQL, et non via le PL /SQL VM, il n'y a donc pas de changement de contexte SQL vers PL/SQL à craindre. Votre application doit se soucier de récupérer un nombre approprié de lignes à chaque aller-retour - suffisamment pour que l'application ne devienne pas trop bavarde et goulot d'étranglement sur le réseau, mais pas trop pour que vous deviez attendre trop longtemps pour que les résultats soient retourné ou pour stocker trop de données en mémoire.

Le retour de collections PL/SQL plutôt qu'un REF CURSOR à une application cliente ne réduira pas le nombre de changements de contexte qui ont lieu. Mais il va avoir un tas d'autres inconvénients, dont le moindre n'est pas l'utilisation de la mémoire. Une collection PL/SQL doit être entièrement stockée dans la zone globale de processus (PGA) (en supposant des connexions de serveur dédiées) sur le serveur de base de données. Il s'agit d'un morceau de mémoire qui doit être alloué à partir de la RAM du serveur. Cela signifie que le serveur va devoir allouer de la mémoire dans laquelle récupérer chaque dernière ligne demandée par chaque client. Cela, à son tour, va considérablement limiter l'évolutivité de votre application et, selon la configuration de la base de données, peut voler la RAM d'autres parties de la base de données Oracle qui seraient très utiles pour améliorer les performances de l'application. Et si vous manquez d'espace PGA, vos sessions commenceront à recevoir des erreurs liées à la mémoire. Même dans les applications purement basées sur PL/SQL, vous ne voudriez jamais récupérer toutes les données dans des collections, vous voudriez toujours les récupérer par lots plus petits, afin de minimiser la quantité de PGA que vous utilisez.

De plus, la récupération de toutes les données en mémoire va rendre l'application beaucoup plus lente. Presque n'importe quel framework vous permettra de récupérer des données selon vos besoins, par exemple, si vous avez un rapport que vous affichez sur des pages de 25 lignes chacune, votre application n'aura besoin de récupérer que les 25 premières lignes avant de peindre le premier écran. Et il n'aurait jamais à récupérer les 25 lignes suivantes à moins que l'utilisateur ne demande la page de résultats suivante. Si vous récupérez les données dans des tableaux comme le propose votre DBA, cependant, vous devrez récupérer toutes les lignes avant que votre application puisse commencer à afficher la première ligne même si l'utilisateur ne veut jamais voir plus que la première poignée de Lignes. Cela va signifier beaucoup plus d'E/S sur le serveur de base de données pour récupérer toutes les lignes, plus de PGA sur le serveur, plus de RAM sur le serveur d'application pour mettre en mémoire tampon le résultat et des attentes plus longues pour le réseau.