sql >> Database teknologi >  >> RDS >> Oracle

GTT-tabelstatistik og SYS.WRI$_OPTSTAT_TAB_HISTORY

Tilbage i 2015 opgraderede jeg vores Oracle 11.2.0.4-databaser til 12.1.0.2 og oplevede nogle præstationsproblemer relateret til vores brug af GTT'er. Jeg bloggede om de problemer her.

Kernen i det problem, jeg prøvede at løse, var, at en adfærdsændring i 12c førte til Oracle-gemmestatistik, at GTT'en har nul rækker, når den ikke gør det. Statistik, der viser antallet af rækker, er lig med nul fører til fuld tabelscanninger og kartesiske produkter på forespørgsler, der involverer GTT. Som jeg sagde i det blogindlæg, brugte vi DBMS_STATS.SET_TABLE_STATS efter at vi havde udfyldt tabellen med data, så hver session ville have ordentlig statistik for at nå frem til en bedre eksekveringsplan.

Efter at vi opgraderede til Oracle 19c, begyndte vi at se andre ydeevneproblemer relateret til GTT. Forespørgsler, der brugte GTT, begyndte at vente på ventehændelsen "cursor pin:S wait on X". Dette kunne have været en adfærdsændring med den nye Oracle-version, men det kunne også have været vores udviklere, der brugte GTT oftere i vores kode og ikke har noget at gøre med den nye version.

For de forespørgsler, der er involveret i Cursor Pin wait-hændelsen, bemærkede jeg et stort antal versioner af SQL-sætningen i Shared Pool. Da jeg spurgte til V$SQL_SHARED_CURSOR, opdagede jeg, at PURGED_CURSOR='Y' for disse SQL-sætninger. Markøren er ved at blive ugyldig.

Da jeg undersøgte dette problem, opdagede jeg, at det, der sker, er, at hver gang vi ringede til DBMS_STATS.SET_TABLE_STATS for at få sessionsbaserede statistikker på GTT, ugyldiggøres alle SQL-sætninger, der bruger den GTT. Derfor ventetiden. Ventetiden var ikke lang, så mange slutbrugere bemærkede ikke engang problemet.

Men så havde vi et nyt problem. Når du foretager et opkald til SET_TABLE_STATS, skriver Oracle en indtastning i SYS.WRI$_OPTSTAT_TAB_HISTORY, og du kan se de værdier, sessionen har sat for tabellens statistik. Som standard gemmer denne tabel 30 dages historik. Bordet voksede meget og forbrugte det meste af SYSAUX. Ind imellem (hver time?) vil Oracle fjerne poster, der er mere end 30 dage gamle. Denne regelmæssige beskæring af denne tabel påvirkede nu slutbrugerens ydeevne negativt. Følgende er en præstationsgraf fra Lighty, der viser virkningen af ​​beskæringen af ​​denne tabel:

Al den skræmmende røde farve er, da de gamle rækker blev fjernet fra SYS.WRI$_OPTSTAT_TAB_HISTORY.

Så mit præstations-"fix" for fem år siden introducerede endnu et præstationsproblem. For at forbedre ydeevnen var det, jeg gjorde, at oprette delt statistik på GTT og stoppe med at bruge sessionsstatistikker. Her er trinene:

--set prefs to SHARED globally      
exec DBMS_STATS.set_global_prefs ( pname => 'GLOBAL_TEMP_TABLE_STATS', pvalue => 'SHARED');
--set the table and index stats
exec dbms_stats.set_table_stats(ownname=>'MY_SCHEMA',tabname=>'MY_GTT_TABLE',numrows=>1000,numblks=>2,avgrlen=>15);
exec dbms_stats.set_index_stats(ownname=>'MY_SCHEMA',indname=>'GTT_INDEX',indlevel=>1,numlblks=>2,numdist=>15,clstfct=>28,numrows=>1000);
-- set prefs back to SESSION
exec DBMS_STATS.set_global_prefs ( pname => 'GLOBAL_TEMP_TABLE_STATS', pvalue => 'SESSION');
-- verify stats set
select num_rows,blocks,last_analyzed,scope
from dba_tab_statistics
where table_name ='MY_GTT_TABLE';
select blevel,leaf_blocks,distinct_keys,num_rows,clustering_factor,last_analyzed,scope
from dba_ind_statistics
where index_name='GTT_INDEX' and owner='MY_SCHEMA';

Når den delte statistik var på plads, fjerner vi opkaldene til DBMS_SET_TABLE_STATS fra vores kode.


  1. Tilføj skiftende rækkefarve til rapporten SQL Server Reporting Services

  2. Ydelsesmyter:Truncate kan ikke rulles tilbage

  3. Overvågning af Percona-distribution for PostgreSQL - nøglemålinger

  4. Sådan kontrolleres brugerrettigheder i MySQL Workbench ved hjælp af GUI