Oracle memperkenalkan fitur baru, grup demi eliminasi, untuk kueri di mana grup demi kolom juga merupakan kunci unik tabel. Seperti banyak fitur baru, yang satu ini masih belum menyelesaikan semua masalah. Masalah muncul ketika nilai kunci dimanipulasi dengan pemanggilan fungsi. Contoh berikut akan mengilustrasikan masalah dengan menggunakan tabel dengan DATE sebagai kunci utama dan dengan mengekstrak tahun diekstraksi menggunakan TO_CHAR atau EXTRACT.
Sebuah tabel dibuat sebagai berikut:
create table bug_test_calendar( cal_name char(17), bus_dt date, updt_timestamp timestamp (6) default systimestamp, constraint pk_bug_test_calendar primary key (bus_dt) ) / insert into bug_test_calendar (bus_dt) select sysdate + 10 * rownum from all_objects where rownum <= 40 / commit;
Ketika kueri yang ditunjukkan di bawah ini dijalankan, menghasilkan hasil sebagai berikut:
select to_char(bus_dt,'YYYY') bus_dt, count(*) ct from bug_test_calendar group by to_char(bus_dt,'YYYY') order by to_char(bus_dt,'YYYY') / BUS_DF CT ------- -- 2020 1 2020 1 ... 2020 1 40 rows returned
Oracle tidak 'tahu' bahwa nilai kunci telah dimanipulasi sehingga tidak lagi unik, oleh karena itu pengoptimal menerapkan eliminasi kelompok demi kelompok berbasis kunci unik dengan hasil yang kurang baik,
Tarif EXTRACT tidak lebih baik, mengembalikan hasil yang sama. Perilaku ini dikendalikan oleh parameter “_optimizer_aggr_groupby_elim”, yang disetel ke true secara default. Karena ini adalah parameter tersembunyi, pengaturannya tidak dilaporkan oleh Oracle dalam tampilan V$PARAMEter atau V$SPPARAMETER. Solusinya adalah dengan hanya mengatur parameter ini ke false. Namun, mengaktifkannya dapat membantu kueri grup-oleh lainnya di mana nilai kunci unik tidak dimanipulasi.
Masukkan Oracle 19c, di mana fungsi ini sebagian diperbaiki:
select to_char(bus_dt,'YYYY') bus_dt, count(*) ct from bug_test_calendar group by to_char(bus_dt,'YYYY') order by to_char(bus_dt,'YYYY') / BUS_DF CT ------- -- 2020 40
Sayangnya EXTRACT masih rusak di 19c:
select to_char(bus_dt,'YYYY') bus_dt, count(*) ct from bug_test_calendar group by extract(year deom bus_dt) order by extract(year deom bus_dt) / BUS_DF CT ------- == 2020 1 2020 1 ... 2020 1 40 rows returned
Jelas diberikan nilai kunci yang benar-benar unik, kueri grup-berdasarkan akan menghasilkan hitungan 1 untuk setiap kunci. Dan, sama jelasnya, Oracle harus dapat mengenali ketika nilai-nilai tidak lagi unik dan menjalankan mekanisme group-by yang tepat. Masih harus dilihat apakah versi setelah 19c akan memperbaiki kondisi kedua dan dengan demikian mengembalikan hasil yang benar tanpa harus mematikan fitur ini.
Ini mungkin tidak memengaruhi setiap penginstalan Oracle yang lebih baru dari 12.1, tetapi perlu diketahui jika hasil yang salah mulai muncul di grup yang dipilih berdasarkan kueri.
# # #
Lihat artikel oleh David Fitzjarrell