sql >> Databasteknik >  >> RDS >> Oracle

Adaptiv dynamisk statistik dödar prestanda i 12.1.0.2 RAC

Efter en nyligen uppgradering till 12.1.0.2 har jag arbetat med ett antal prestandaproblem. Många sådana problem är relaterade till dålig SQL och ett antal problem som jag har löst som jag har bevisat var problem i den gamla 11.2.0.4-versionen. Detta betyder bara att det alltid har varit ett problem. Men folk tar tillfället i akt med uppgraderingen för att få mig att fixa saker som har varit trasiga ett bra tag.

När jag tittade på prestandaproblem har jag stött på två SQL-satser som håller på att bli svin i vårt system. Här är en skärmdump av de två SQL-satserna som ses i Lighty:

Vi kan se att den första SQL-satsen (SQL ID 4b4wp0a8dvkf0) förbrukar CPU och väntar på läsningar från kontrollfilen. Den andra SQL-satsen (SQL ID frjd8zfy2jfdq) använder massor av CPU och har ett antal andra väntehändelser också. Här är SQL-texten för dessa satser.

SQL ID:frjd8zfy2jfdq

SELECT
    executions
    ,end_of_fetch_count
    ,elapsed_time / px_servers elapsed_time
    ,cpu_time / px_servers cpu_time
    ,buffer_gets / executions buffer_gets
  FROM
    (
      SELECT
          SUM (executions) AS executions
          ,SUM (
            CASE
              WHEN px_servers_executions > 0
              THEN px_servers_executions
              ELSE executions
            END
          ) 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
        FROM
          gv$sql
        WHERE
          executions > 0
          AND sql_id = : 1
          AND parsing_schema_name = : 2

SQL ID:4b4wp0a8dvkf0

SELECT
    executions
    ,end_of_fetch_count
    ,elapsed_time / px_servers elapsed_time
    ,cpu_time / px_servers cpu_time
    ,buffer_gets / executions buffer_gets
  FROM
    (
      SELECT
          SUM (executions_delta) AS EXECUTIONS
          ,SUM (
            CASE
              WHEN px_servers_execs_delta > 0
              THEN px_servers_execs_delta
              ELSE executions_delta
            END
          ) 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
        FROM
          DBA_HIST_SQLSTAT s
          ,V$DATABASE d
          ,DBA_HIST_SNAPSHOT sn
        WHERE
          s.dbid = d.dbid
          AND bitand (
            nvl (
              s.flag
              ,0
            )
            ,1
          ) = 0
          AND sn.end_interval_time > (
            SELECT
                systimestamp AT TIME ZONE dbtimezone
              FROM
                dual
          ) - 7
          AND s.sql_id = : 1
          AND s.snap_id = sn.snap_id
          AND s.instance_number = sn.instance_number
          AND s.dbid = sn.dbid
          AND parsing_schema_name = : 2
    )
 
    )
 

Båda dessa är en del av de nya Adaptive Query Optimization-funktionerna nu i 12c. Mer specifikt relaterar dessa till den automatiska dynamiska statistikdelen av den här funktionen. SQL ID frjd8zfy2jfdq är Oracle som hämtar information om SQL-satsprestanda från GV$SQL. SQL ID 4b4wp0a8dvkf0 är Oracle som hämtar samma information om SQL-satsprestanda från Active Session History-tabellerna.

Bertand Drouvot diskuterar detta på sin blogg här:https://bdrouvot.wordpress.com/2014/10/17/watch-out-for-optimizer_adaptive_features-as-it-may-have-a-huge-negative-impact/

Dessutom satt jag i en session av Christian Antognini på Oak Table World 2015 där han nämnde dessa SQL-satser. Hans bilder från OTW är i stort sett desamma som dessa:

http://www.soug.ch/fileadmin/user_upload/SIGs/SIG_150521_Tuning_R/Christian_Antognini_AdaptiveDynamicSampling_trivadis.pdf

Dessa länkar ovan och MOS-anteckningarna som jag refererar till nedan gav mycket av grunden för den information jag presenterar här.

Alla Adaptive Query Optimization-funktioner är tänkta att göra DBA:s liv bättre. De är tänkta att hjälpa Optimizern att fatta bättre beslut, även efter att en SQL-sats har börjat köras. I det här specifika fallet ska dessa frågor hjälpa CBO att få bättre statistik, även om statistiken saknas. Detta kan hjälpa till att förbättra SQL-prestandan, men som jag upptäckte i mitt fall hämmar det systemets övergripande prestanda.

För mer om adaptiv frågeoptimering, se anmärkning 2031605.1. Detta leder dig till andra anteckningar, men i synnerhet till denna diskussion, Note 2002108.1 Automatic Dynamic Statistics.

Det som gör saken värre är att mitt produktionssystem som ser detta beteende är Oracle RAC. När SQL ID frjd8zfy2jfdq utförs på Oracle RAC-system, används parallella frågor, vilket är uppenbart från min skärmdump av enq:PS – påstående och "PX%" vänta-händelser.

Vi kan stänga av dynamisk sampling enligt följande:

alter system set optimizer_dynamic_sampling=0 scope=both;

Standardvärdet för denna parameter är 2.

För mig tar dessa frågor upp resurser och påverkar databasens övergripande prestanda. Ändå är dessa funktioner utformade för att förbättras prestanda. Det finns alltid en risk att om jag stänger av funktionen för att hjälpa prestanda inom ett område, kommer det att skada prestandan inom ett annat område. Men eftersom optimizer_dynamic_sampling<>11 för mig, använder jag inte den funktionen till fullo så jag får inte alla fördelar jag skulle kunna vara. Dessutom är vår kod inte beroende av att dynamisk sampling ska ske. Så det är säkert för mig att stänga av det här.

Efter att ha ändrat parametern kunde jag se en omedelbar förändring som visas nedan.

Den röda linjen anger när jag gjorde ändringen. Det är tydligt att ASH-versionen av denna fråga inte längre körs. V$SQL-versionen körs fortfarande men ser inte längre parallella frågeväntningshändelser. Det förbrukar mest bara CPU nu. Jag anser detta framsteg, men inte som en fullständig upplösning.

Som en sidoanteckning kunde jag ha stängt av alla funktioner för Adaptive Query Optimization med följande:

alter system set optimizer_adaptive_features=false scope=both;

Men jag vet att jag har frågor som "njuter av" Adaptive Join Optimization och jag vill inte stänga av allt, bara dynamisk sampling.

Så nu vad ska jag göra med SQL ID frjd8zfy2jfdq? Låt oss se om vi kan lösa det återstående problemet. Från en av MOS-anteckningarna jag länkade ovan vet jag att vi kan ställa in denna dolda parameter:

alter system set "_optimizer_dsdir_usage_control"=0 scope=both;

Standardvärdet för denna dolda parameter var 126 i mitt 12.1.0.2-system. Jag hittade standardinställningen med följande:

select a.ksppinm name, b.ksppstvl value, b.ksppstdf deflt,
from
  sys.x$ksppi a,
  sys.x$ksppcv b
where  a.indx = b.indx
  and  a.ksppinm like '\_%' escape '\'
  and  a.ksppinm like '%dsdir%'
order by name;

Det här värdet är viktigt om jag vill ställa tillbaka det utan att behöva ta bort parametern från SPFILE, vilket skulle kräva driftstopp.

Jag kan nu fortsätta med att ändra denna dolda parameter och ställa in den på noll. Så här ser den SQL-satsen ut i Lighty efter ändringen:

Ser ut att vara "uppdrag fullbordat" när det gäller att stoppa dessa två SQL-satser från att köras.

De som kör 12.1.0.2 på Oracle RAC kanske vill verifiera att dessa två SQL-satser inte orsakar sina egna prestandaproblem.

Det här verkar vara ett av de fall där en funktion som ska hjälpa prestanda faktiskt gör tvärtom.


  1. Mysql:hur väljer man grupper som har vissa värden?

  2. Vänligen hjälp med STRING_SPLIT-förbättringar

  3. Hur man skapar en tabell från en annan tabell i SQL

  4. Arbeta med Structured Query Language (SQL) med Microsoft Access 2010, 2013, 2016 och 2019