Setelah peningkatan terbaru ke 12.1.0.2, saya telah mengatasi sejumlah masalah kinerja. Banyak masalah seperti itu terkait dengan SQL yang buruk dan sejumlah masalah yang telah saya selesaikan yang telah saya buktikan adalah masalah dalam rilis 11.2.0.4 yang lama. Ini hanya berarti itu selalu menjadi masalah. Tetapi orang-orang mengambil kesempatan untuk meningkatkan agar saya memperbaiki hal-hal yang telah rusak cukup lama.
Saat melihat masalah kinerja, saya menemukan dua pernyataan SQL yang menjadi babi di sistem kami. Berikut adalah tangkapan layar dari dua pernyataan SQL seperti yang terlihat di Lighty:
Kita dapat melihat bahwa pernyataan SQL pertama (SQL ID 4b4wp0a8dvkf0) menggunakan CPU dan menunggu pembacaan dari File Kontrol. Pernyataan SQL kedua (SQL ID frjd8zfy2jfdq) menggunakan banyak CPU dan memiliki sejumlah acara tunggu lainnya juga. Berikut adalah teks SQL dari pernyataan tersebut.
ID SQL: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
ID SQL: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
)
)
Keduanya adalah bagian dari fitur Pengoptimalan Kueri Adaptif yang baru sekarang di 12c. Lebih khusus lagi, ini terkait dengan bagian Statistik Dinamis Otomatis dari fitur ini. ID SQL frjd8zfy2jfdq adalah Oracle yang memperoleh informasi tentang kinerja pernyataan SQL dari GV$SQL. ID SQL 4b4wp0a8dvkf0 adalah Oracle yang memperoleh informasi yang sama tentang kinerja pernyataan SQL dari tabel Riwayat Sesi Aktif.
Bertand Drouvot membahas ini di blognya di sini:https://bdrouvot.wordpress.com/2014/10/17/watch-out-for-optimizer_adaptive_features-as-it-may-have-a-huge-negative-impact/
Selain itu, saya duduk di sesi oleh Christian Antognini di Oak Table World 2015 di mana dia menyebutkan pernyataan SQL ini. Slide-nya dari OTW hampir sama dengan ini:
http://www.soug.ch/fileadmin/user_upload/SIGs/SIG_150521_Tuning_R/Christian_Antognini_AdaptiveDynamicSampling_trivadis.pdf
Tautan di atas dan Catatan MOS yang saya rujuk di bawah memberikan banyak informasi yang saya sajikan di sini.
Semua fitur Pengoptimalan Kueri Adaptif seharusnya membuat kehidupan DBA lebih baik. Mereka seharusnya membantu Pengoptimal membuat keputusan yang lebih baik, bahkan setelah pernyataan SQL mulai dijalankan. Dalam kasus khusus ini, kueri ini seharusnya membantu CBO mendapatkan statistik yang lebih baik, bahkan jika statistiknya hilang. Ini dapat membantu meningkatkan kinerja SQL, tetapi seperti yang saya temukan dalam kasus saya, ini menghambat kinerja sistem secara keseluruhan.
Untuk lebih lanjut tentang Pengoptimalan Kueri Adaptif, lihat Catatan 2031605.1. Ini akan membawa Anda ke catatan lain, tetapi khususnya untuk diskusi ini, Catatan 2002108.1 Statistik Dinamis Otomatis.
Yang memperburuk keadaan adalah sistem produksi saya yang melihat perilaku ini adalah Oracle RAC. Ketika SQL ID frjd8zfy2jfdq dilakukan pada sistem Oracle RAC, query paralel digunakan yang terlihat jelas dari tangkapan layar saya oleh enq:PS – contention dan “PX%” wait events.
Kita dapat mengubah sampling dinamis sebagai berikut:
ubah set sistem optimizer_dynamic_sampling=0 scope=both;
Nilai default parameter ini adalah 2.
Bagi saya, kueri ini menghabiskan sumber daya dan memengaruhi kinerja basis data secara keseluruhan. Namun fitur ini dirancang untuk meningkatkan pertunjukan. Selalu ada risiko bahwa jika saya mematikan fitur untuk membantu kinerja di satu area, itu akan mengganggu kinerja di area lain. Tapi karena optimizer_dynamic_sampling<>11 untuk saya, saya tidak menggunakan fitur itu secara maksimal sehingga saya tidak mendapatkan semua manfaat yang saya bisa. Selain itu, kode kami tidak bergantung pada pengambilan sampel dinamis untuk terjadi. Jadi aman bagi saya untuk mematikan ini.
Setelah mengubah parameter, saya bisa melihat perubahan langsung seperti yang ditunjukkan di bawah ini.
Garis merah menunjukkan waktu saya melakukan perubahan. Jelas bahwa versi ASH dari kueri ini tidak lagi dijalankan. Versi V$SQL masih dijalankan tetapi tidak lagi melihat peristiwa menunggu kueri paralel. Sebagian besar hanya mengkonsumsi CPU sekarang. Saya menganggap kemajuan ini, tetapi bukan resolusi penuh.
Sebagai catatan tambahan, saya dapat menonaktifkan semua fitur Pengoptimalan Kueri Adaptif dengan yang berikut:
alter system set optimizer_adaptive_features=false scope=both;
Namun saya tahu bahwa saya memiliki kueri "menikmati" Pengoptimalan Gabung Adaptif dan saya tidak ingin menonaktifkan semuanya, hanya pengambilan sampel dinamis.
Jadi sekarang apa yang harus dilakukan dengan ID SQL frjd8zfy2jfdq? Mari kita lihat apakah kita dapat menyelesaikan masalah yang tersisa. Dari salah satu Catatan MOS yang saya tautkan di atas, saya tahu bahwa kita dapat mengatur parameter tersembunyi ini:
alter system set "_optimizer_dsdir_usage_control"=0 scope=both;
Nilai default untuk parameter tersembunyi ini adalah 126 di sistem 12.1.0.2 saya. Saya menemukan pengaturan default dengan yang berikut:
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;
Nilai ini penting jika saya ingin mengaturnya kembali tanpa harus mengeluarkan parameter dari SPFILE, yang akan membutuhkan waktu henti.
Sekarang saya dapat melanjutkan dengan mengubah parameter tersembunyi ini dan menyetelnya ke nol. Berikut adalah tampilan pernyataan SQL di Lighty setelah perubahan:
Tampaknya "misi tercapai" dalam menghentikan kedua pernyataan SQL itu agar tidak dieksekusi.
Mereka yang menjalankan 12.1.0.2 di Oracle RAC mungkin ingin memverifikasi bahwa kedua pernyataan SQL ini tidak menyebabkan masalah kinerja mereka sendiri.
Tampaknya ini adalah salah satu kasus di mana fitur yang seharusnya membantu kinerja justru melakukan hal yang sebaliknya.