Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Dynamisches Sampling bringt mich um in 12c

Vor elf Tagen habe ich darüber gebloggt, wie Adaptive Dynamic Stats Ressourcen in meinen RAC-Produktionsdatenbanken verbraucht hat.

Nachdem ich dieses Feuer gelöscht hatte, untersuchte ich einige Abfragen mit schlechter Leistung, die von unseren QA-Mitarbeitern in Test- und anderen Nicht-Produktionsdatenbanken gemeldet wurden. Ich habe es so gemacht, wie es jeder gute Oracle-DBA tun würde. Ich habe einen Aufruf einer gespeicherten Prozedur gesammelt, der das Problem dupliziert hat. In meiner Sitzung habe ich eine SQL-Ablaufverfolgung gestartet und die gespeicherte Prozedur ausgeführt. Es dauerte 50 Sekunden, bis ich fertig war, während es früher 5 Sekunden oder weniger dauerte, bevor ich von 11.2.0.4 auf 12.1.0.2 aktualisierte. Diese gespeicherte Prozedur enthält eine Reihe von SQL-Anweisungen, und ein SQL-Trace schien ein logischer Ausgangspunkt zu sein. Ich musste wissen, welche SQL-Anweisung in der Prozedur die Probleme verursachte.

Ich habe die SQL-Trace-Datei durch TKPROF laufen lassen und war von den Ergebnissen überrascht. Die SQL-Anweisungen in der gespeicherten Prozedur schienen ziemlich schnell ausgeführt zu werden. Aber ich wurde von vielen Aussagen begrüßt, die der folgenden ähnelten:

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

Das ist Dynamic Sampling bei der Arbeit. Als ich mir alle Dynamic Sampling-Anweisungen ansah, die in meiner Trace-Datei ausgeführt wurden, konnte ich feststellen, dass diese 45 Sekunden der Gesamtlaufzeit ausmachten! Huch!

Dynamic Sampling soll mir dabei helfen. Der Zeitaufwand für das Abrufen einiger Beispielstatistiken soll viel geringer sein als die Zeitersparnis durch Ausführen der SQL-Anweisung mit besseren Statistiken. Wenn dies nicht der Fall ist, kann die Leistung Ihrer SQL-Anweisung darunter leiden, wie es in meinem Fall der Fall war.

Eine Sache, die ich interessant fand, war, dass diese Dynamic Sampling-Abfragen einmal für jede Tabelle und einmal für jeden ihrer Indizes ausgeführt wurden. Eine der an meiner Abfrage beteiligten Tabellen enthält 7 Indexe, also hatte ich für diese eine Tabelle 8 Dynamic Sampling-Abfragen!

In meinem Blogbeitrag vor 11 Tagen hatte ich den Parameter optimizer_dynamic_sampling auf 0 gesetzt, wodurch diese Abfragen nicht mehr ausgeführt werden. Ich hatte diese Änderung noch nicht in unsere Testumgebung eingefügt, also musste ich das tun. Sobald ich das tat, normalisierte sich die Abfrageleistung wieder. Der Standardwert dieses Parameters für meine Datenbank ist 2. Ihr Standardwert kann je nach Wert der Einstellung optimizer_features_enable unterschiedlich sein. Laut diesem Blogbeitrag bedeutet ein Wert von 2, dass dynamisches Sampling einsetzt, wenn mindestens eine der Tabellen keine Statistiken enthält. Aber um ehrlich zu sein, dynamisches Sampling bringt mir keine Vorteile und schadet mir nur. Also lasse ich es erstmal ganz weg.