Après une récente mise à niveau vers 12.1.0.2, j'ai travaillé sur un certain nombre de problèmes de performances. Beaucoup de ces problèmes sont liés à un mauvais SQL et un certain nombre de problèmes que j'ai résolus, j'ai prouvé qu'ils étaient des problèmes dans l'ancienne version 11.2.0.4. Cela signifie simplement que cela a toujours été un problème. Mais les gens profitent de la mise à niveau pour me faire réparer des choses qui ont été cassées pendant un bon moment.
En examinant les problèmes de performances, j'ai rencontré deux instructions SQL qui deviennent des porcs dans notre système. Voici une capture d'écran des deux instructions SQL telles qu'elles apparaissent dans Lighty :
Nous pouvons voir que la première instruction SQL (ID SQL 4b4wp0a8dvkf0) consomme du CPU et attend des lectures à partir du fichier de contrôle. La deuxième instruction SQL (ID SQL frjd8zfy2jfdq) utilise beaucoup de CPU et comporte également un certain nombre d'autres événements d'attente. Voici le texte SQL de ces instructions.
Identifiant SQL :frjd8zfy2jfdq
SÉLECTIONNER
exécutions
,end_of_fetch_count
,elapsed_time / px_servers elapsed_time
,cpu_time / px_servers cpu_time
,buffer_gets / exécutions buffer_gets
DE
(
SÉLECTIONNER
SUM (exécutions) AS exécutions
,SOMME (
CAS
QUAND px_servers_executions> 0
PUIS px_servers_executions
ELSE exécutions
FIN
) AS px_servers
,SUM (end_of_fetch_count) AS end_of_fetch_count
,SUM (elapsed_time) AS elapsed_time
,SUM (cpu_time) AS cpu_time
,SUM (buffer_gets) AS buffer_gets
DE
gv$sql
OÙ
exécutions> 0
AND sql_id = :1
AND parsing_schema_name = :2
Identifiant SQL :4b4wp0a8dvkf0
SÉLECTIONNER
exécutions
,end_of_fetch_count
,elapsed_time / px_servers elapsed_time
,cpu_time / px_servers cpu_time
,buffer_gets / exécutions buffer_gets
DE
(
SÉLECTIONNER
SUM (executions_delta) AS EXECUTIONS
,SOMME (
CAS
QUAND px_servers_execs_delta> 0
PUIS px_servers_execs_delta
ELSE executions_delta
FIN
) AS px_servers
,SUM (end_of_fetch_count_delta) AS end_of_fetch_count
,SUM (elapsed_time_delta) AS ELAPSED_TIME
,SUM (cpu_time_delta) AS CPU_TIME
,SUM (buffer_gets_delta) AS BUFFER_GETS
DE
DBA_HIST_SQLSTAT
,V$DATABASE d
,DBA_HIST_SNAPSHOT sn
OÙ
s.dbid =d.dbid
AND bitand (
nvl (
s.flag
,0
)
,1
) =0
AND sn.end_interval_time> (
SÉLECTIONNER
horodatage AT TIME ZONE dbtimezone
DE
double
) - 7
ET s.sql_id = :1
ET s.snap_id =sn.snap_id
AND s.instance_number =sn.instance_number
ET s.dbid =sn.dbid
AND parsing_schema_name = :2
)
)Ces deux éléments font partie des nouvelles fonctionnalités d'optimisation adaptative des requêtes désormais disponibles dans 12c. Plus précisément, ceux-ci se rapportent à la partie Statistiques dynamiques automatiques de cette fonctionnalité. L'ID SQL frjd8zfy2jfdq est qu'Oracle obtient des informations sur les performances des instructions SQL à partir de GV$SQL. L'ID SQL 4b4wp0a8dvkf0 signifie qu'Oracle obtient les mêmes informations sur les performances des instructions SQL à partir des tables Active Session History.
Bertand Drouvot en parle sur son blog ici :https://bdrouvot.wordpress.com/2014/10/17/watch-out-for-optimizer_adaptive_features-as-it-may-have-a-huge-negative-impact/
De plus, j'ai assisté à une session de Christian Antognini à Oak Table World 2015 où il a mentionné ces instructions SQL. Ses diapositives d'OTW sont à peu près les mêmes que celles-ci :
http://www.soug.ch/fileadmin/user_upload/SIGs/SIG_150521_Tuning_R/Christian_Antognini_AdaptiveDynamicSampling_trivadis.pdf
Ces liens ci-dessus et les notes MOS auxquelles je fais référence ci-dessous ont fourni une grande partie de la base des informations que je présente ici.
Toutes les fonctionnalités d'Adaptive Query Optimization sont censées améliorer la vie du DBA. Ils sont censés aider l'optimiseur à prendre de meilleures décisions, même après le début de l'exécution d'une instruction SQL. Dans ce cas précis, ces requêtes sont censées aider le CBO à obtenir de meilleures statistiques, même si les statistiques manquent. Cela peut aider à améliorer les performances SQL, mais comme je l'ai constaté dans mon cas, cela entrave les performances globales du système.
Pour plus d'informations sur l'optimisation adaptative des requêtes, consultez la note 2031605.1. Cela vous mènera à d'autres notes, mais en particulier à cette discussion, Note 2002108.1 Statistiques dynamiques automatiques.
Pire encore, mon système de production voyant ce comportement est Oracle RAC. Lorsque l'ID SQL frjd8zfy2jfdq est exécuté sur les systèmes Oracle RAC, une requête parallèle est utilisée, ce qui ressort clairement de ma capture d'écran par l'enq :PS - contention et "PX%" événements d'attente.
Nous pouvons activer l'échantillonnage dynamique comme suit :
modifier l'ensemble système Optimizer_dynamic_sampling=0 scope=both ;
La valeur par défaut de ce paramètre est 2.
Pour moi, ces requêtes consomment des ressources et ont un impact sur les performances globales de la base de données. Pourtant, ces fonctionnalités sont conçues pour améliorer performance. Il y a toujours un risque que si je désactive la fonctionnalité pour améliorer les performances dans un domaine, cela nuira aux performances dans un autre domaine. Mais depuis l'optimizer_dynamic_sampling<>11 pour moi, je n'utilise pas cette fonctionnalité au maximum, donc je n'obtiens pas tous les avantages que je pourrais en tirer. De plus, notre code ne repose pas sur l'échantillonnage dynamique pour se produire. Je peux donc désactiver cette option en toute sécurité.
Après avoir changé le paramètre, j'ai pu voir un changement immédiat comme indiqué ci-dessous.
La ligne rouge indique l'heure à laquelle j'ai effectué le changement. Il est clair que la version ASH de cette requête ne s'exécute plus. La version V$SQL est toujours en cours d'exécution mais ne voit plus les événements d'attente de requête parallèles. Cela ne fait que consommer du CPU maintenant. Je considère ce progrès, mais pas une résolution complète.
En passant, j'aurais pu désactiver toutes les fonctionnalités d'optimisation adaptative des requêtes avec ce qui suit :
modifier le jeu de système optimiser_adaptive_features=false scope=both ;Mais je sais que j'ai des requêtes "appréciant" l'optimisation adaptative des jointures et je ne veux pas tout désactiver, juste l'échantillonnage dynamique.
Alors maintenant, que faire avec l'ID SQL frjd8zfy2jfdq ? Voyons si nous pouvons résoudre le problème restant. D'après l'une des notes MOS que j'ai liées ci-dessus, je sais que nous pouvons définir ce paramètre caché :
alter system set "_optimizer_dsdir_usage_control"=0 scope=both ;La valeur par défaut de ce paramètre caché était 126 dans mon système 12.1.0.2. J'ai trouvé le paramètre par défaut avec ce qui suit :
sélectionnez un nom.ksppinm, une valeur b.ksppstvl, un défaut b.ksppstdf,desys.x$ksppi a,sys.x$ksppcv boù a.indx =b.indxet a.ksppinm comme '\_%' escape '\'et a.ksppinm comme '%dsdir%'commander par nom ;
Cette valeur est importante au cas où je voudrais la rétablir sans avoir à retirer le paramètre du SPFILE, ce qui nécessiterait un temps d'arrêt.
Je peux maintenant procéder à la modification de ce paramètre caché et le mettre à zéro. Voici à quoi ressemble cette instruction SQL dans Lighty après le changement :
Semble être "mission accomplie" en arrêtant l'exécution de ces deux instructions SQL.
Ceux qui exécutent 12.1.0.2 sur Oracle RAC voudront peut-être vérifier que ces deux instructions SQL ne causent pas leurs propres problèmes de performances.
Cela semble être l'un de ces cas où une fonctionnalité censée améliorer les performances fait en réalité le contraire.