Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Statistik Tabel GTT dan SYS.WRI$_OPTSTAT_TAB_HISTORY

Kembali pada tahun 2015, saya memutakhirkan database Oracle 11.2.0.4 kami ke 12.1.0.2 dan mengalami beberapa masalah kinerja terkait dengan penggunaan GTT kami. Saya membuat blog tentang masalah-masalah itu di sini.

Inti dari masalah yang saya coba pecahkan adalah bahwa perubahan perilaku dalam 12c mengarah ke statistik penyimpanan Oracle bahwa GTT memiliki baris nol ketika tidak. Statistik yang menunjukkan jumlah baris sama dengan nol mengarah ke pemindaian tabel lengkap dan produk kartesius pada kueri yang melibatkan GTT. Seperti yang saya nyatakan dalam posting blog itu, kami menggunakan DBMS_STATS.SET_TABLE_STATS setelah kami mengisi tabel dengan data sehingga setiap sesi akan memiliki statistik yang tepat untuk sampai pada rencana eksekusi yang lebih baik.

Setelah kami meningkatkan ke Oracle 19c, kami mulai melihat masalah kinerja lain yang terkait dengan GTT. Kueri yang menggunakan GTT mulai menunggu pada acara tunggu “pin kursor:S wait on X”. Ini bisa jadi merupakan perubahan perilaku dengan versi Oracle yang baru, tetapi bisa juga karena pengembang kami lebih sering menggunakan GTT dalam kode kami dan tidak ada hubungannya dengan versi baru.

Untuk kueri yang terlibat dalam acara tunggu Pin Kursor, saya melihat sejumlah besar versi pernyataan SQL di Kumpulan Bersama. Ketika saya menanyakan V$SQL_SHARED_CURSOR, saya menemukan bahwa PURGED_CURSOR='Y' untuk pernyataan SQL ini. Kursor menjadi tidak valid.

Saat meneliti masalah ini, saya menemukan bahwa apa yang terjadi adalah bahwa setiap kali kami memanggil DBMS_STATS.SET_TABLE_STATS untuk mendapatkan statistik berbasis sesi di GTT, itu membatalkan semua pernyataan SQL yang menggunakan GTT itu. Oleh karena itu menunggu. Penantiannya tidak lama sehingga banyak pengguna akhir bahkan tidak menyadari masalah ini.

Tapi kemudian kami mendapat masalah baru. Saat Anda melakukan panggilan ke SET_TABLE_STATS, Oracle menulis entri ke SYS.WRI$_OPTSTAT_TAB_HISTORY dan Anda dapat melihat nilai yang ditetapkan sesi untuk statistik tabel. Secara default, tabel ini menyimpan riwayat 30 hari. Tabel tumbuh sangat besar dan menghabiskan sebagian besar SYSAUX. Seringkali (setiap jam?) Oracle akan menghapus entri yang berumur lebih dari 30 hari. Pemangkasan rutin tabel ini sekarang berdampak negatif pada kinerja pengguna akhir. Berikut adalah grafik kinerja dari Lighty yang menunjukkan dampak pemangkasan tabel ini:

Semua warna merah menakutkan itu adalah ketika baris lama dihapus dari SYS.WRI$_OPTSTAT_TAB_HISTORY.

Jadi kinerja saya "memperbaiki" lima tahun lalu memperkenalkan masalah kinerja lain. Untuk meningkatkan kinerja, yang saya lakukan adalah membuat statistik bersama di GTT dan berhenti menggunakan statistik sesi. Berikut langkah-langkahnya:

--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';

Setelah statistik bersama diterapkan, kami menghapus panggilan ke DBMS_SET_TABLE_STATS dari kode kami.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apakah kunci asing benar-benar diperlukan dalam desain basis data?

  2. Cara membuat menu di SQLPlus atau PL/SQL

  3. Apa yang sebenarnya digunakan LISTAGG dengan ORDER BY NULL sebagai kriteria pesanan?

  4. Bagaimana cara memilih semua kolom dari tabel, ditambah kolom tambahan seperti ROWNUM?

  5. cara memilih daftar 10.000 id unik dari dual di Oracle SQL