Elf dagen geleden blogde ik over hoe Adaptive Dynamic Stats bronnen in mijn productie-RAC-databases opslokte.
Nadat ik dat vuur had geblust, was ik bezig met het onderzoeken van enkele slecht presterende query's die werden gerapporteerd door onze QA-mensen in Test- en andere niet-productiedatabases. Ik deed wat elke goede Oracle DBA zou doen. Ik verzamelde een opgeslagen procedureaanroep die het probleem dupliceerde. In mijn sessie startte ik een SQL-tracering en voerde ik de opgeslagen procedure uit. Het duurde 50 seconden om te voltooien, terwijl het 5 seconden of minder duurde voordat ik een upgrade uitvoerde van 11.2.0.4 naar 12.1.0.2. Deze opgeslagen procedure bevat een aantal SQL-instructies en een SQL-trace leek een logische plek om te beginnen. Ik moest weten welke SQL-instructie in de procedure de problemen veroorzaakte.
Ik liet het SQL-traceerbestand door TKPROF lopen en was verrast door de resultaten. De SQL-instructies in de opgeslagen procedure leken vrij snel te worden uitgevoerd. Maar ik werd begroet door veel uitspraken die vergelijkbaar waren met de volgende:
SELECT /* DS_SVC */ /*+ dynamic_sampling(0) no_sql_tune no_monitoring optimizer_features_enable(default) no_parallel */ SUM(C1) FROM (SELECT /*+ qb_name("innerQuery") INDEX_FFS( "XXX" "INDEX_NAME") */ 1 AS C1 FROM "OWNER"."TABLE_NAME" SAMPLE BLOCK(71.048, 8) SEED(1) "XXX") innerQuery
Dit is Dynamic Sampling aan het werk. Toen ik naar alle Dynamic Sampling-instructies keek die in mijn traceerbestand werden uitgevoerd, kon ik vaststellen dat deze 45 seconden van de totale runtime uitmaakten! Klopt!
Dynamic Sampling zou me moeten helpen. De tijd die wordt besteed aan het verkrijgen van enkele voorbeeldstatistieken wordt verondersteld veel kleiner te zijn dan de hoeveelheid tijd die wordt bespaard door de SQL-instructie met betere statistieken uit te voeren. Als dit niet het geval is, kunnen de prestaties van uw SQL-statement eronder lijden, zoals bij mij het geval was.
Ik merkte op dat een ding dat ik interessant vond, was dat deze Dynamic Sampling-query's één keer werden uitgevoerd voor elke tabel en één keer voor elk van zijn indexen. Een van de tabellen in mijn zoekopdracht heeft 7 indexen, dus voor die ene tabel had ik 8 Dynamic Sampling-query's!
In mijn blogpost van 11 dagen geleden had ik de parameter optimizer_dynamic_sampling op 0 gezet, waardoor deze query's niet meer worden uitgevoerd. Ik had die wijziging nog niet in onze testomgeving doorgevoerd, dus dat moest ik doen. Zodra ik dat deed, keerden de queryprestaties terug naar normaal. De standaardwaarde van deze parameter voor mijn database is 2. Uw standaardwaarde kan verschillen, afhankelijk van de waarde van de instelling optimizer_features_enable. Volgens deze blogpost betekent een waarde van 2 dat dynamische bemonstering in werking treedt wanneer ten minste één van de tabellen geen statistieken heeft. Maar om eerlijk te zijn, dynamische bemonstering levert me geen voordelen op en doet me alleen maar schade. Dus ik laat het nu maar in zijn geheel.