Kueri di Tampilan berjalan lebih lambat daripada kueri langsung - di Oracle

Saya mencoba membuat tampilan dengan parameter untuk mendapatkan data secara dinamis.
(Saya tidak dapat menggunakan kondisi WHERE karena pernyataan pilih itu sendiri berubah berdasarkan parameter)

Untuk ini, saya menulis sebuah prosedur yang mengembalikan saya data yang diperlukan sebagai tipe objek Oracle.

FUNCTION get_data(p_pk_id  NUMBER, p_tab_type VARCHAR2)
RETURN M_TYPE_DATA_TAB
AS
v_table_collection M_TYPE_DATA_TAB;
BEGIN

-- my sql query which will change based on the params

RETURN v_table_collection;
END;

dan saya menjalankan kueri pemilihan sebagai berikut.

SELECT * FROM TABLE(get_data(12345, 'MYTAB'));

yang memberi saya data dalam waktu kurang dari 1 detik.

untuk pernyataan pilih yang sama saya telah membuat tampilan sebagai

CREATE OR REPLACE VIEW my_view
AS SELECT * FROM TABLE(get_data(12345, 'MYTAB'));

jika saya menanyakan tampilan

SELECT * FROM my_view

dibutuhkan lebih dari 6 detik untuk mendapatkan data yang sama.

Adakah yang tahu mengapa ada perbedaan besar untuk mengkueri data yang sama.
Apakah tampilannya memerlukan waktu lebih lama dibandingkan kueri biasa?


person Madhusudhan Dollu    schedule 12.12.2013    source sumber
comment
Test case yang dapat direproduksi sepenuhnya akan sangat membantu dalam hal ini. Secara umum, menambahkan select * from di atas sesuatu tidak masalah. Kami perlu tahu persis apa yang membuat kasus Anda istimewa.   -  person Jon Heller    schedule 13.12.2013
comment
@jonearles: seperti yang dikatakan Guntram Blohm, ketika saya melakukan kueri dari tampilan, ia melakukan pemindaian tabel penuh sedangkan kueri langsung menggunakan semua indeks tabel dasar untuk mendapatkan data lebih cepat.   -  person Madhusudhan Dollu    schedule 13.12.2013
comment
Itu membantu, tapi kita masih belum menemukan akar masalahnya. Saya ingin tahu mengapa menggunakan FTS dan bukan indeks.   -  person Jon Heller    schedule 13.12.2013


Jawaban (2)


Rencana eksekusi pada setiap pernyataan akan memberi Anda lebih banyak detail tentang apa yang terjadi. Coba gunakan beberapa alat Oracle yang disediakan untuk menyelidiki apa yang sebenarnya terjadi dalam setiap kasus.

Coba lakukan:

 SELECT/*+gather_plan_statistics*/ * FROM TABLE(get_data(12345, 'MYTAB'));

lalu lakukan:

 SELECT/*+gather_plan_statistics*/ * FROM my_view

Ini akan memberi Anda rencana eksekusi aktual untuk pernyataan tersebut.

Ngomong-ngomong, Anda perlu memilih pada tampilan V_$SQL_PLAN dan V_$SQL untuk menggunakan Gather_plan_statistics seperti di atas.

person Tomás    schedule 12.12.2013
comment
Perhatikan juga bahwa hibah diperlukan pada tampilan V_$SQL... daripada V$SQL... Ini karena tampilan V$SQL sebenarnya adalah sinonim. Namun Anda kemudian dapat memilih dari sinonim tersebut. - person Tomás; 13.12.2013

Google untuk "jelaskan rencana", dan periksa rencana eksekusi untuk kedua pernyataan tersebut. Tanpa fungsi yang lengkap, sulit untuk mengatakan apa pun. Namun saya berasumsi bahwa pengoptimal melakukan "pengoptimalan umum" pada tampilan, dan ketika Anda memilih dari tampilan, pengoptimalan umum tersebut digunakan. Saat Anda memilih secara langsung, tanpa tampilan, pengoptimal juga mempertimbangkan internal fungsi Anda.

Coba jelaskan rencana pada pernyataan berbeda yang dipilih dari tampilan. Apakah "bagian internal", yang menjalankan fungsinya, sama di setiap kasus?

person Guntram Blohm    schedule 12.12.2013
comment
Ya, saya melihat perbedaan besar dalam rencana penjelasan untuk tampilan dan kueri langsung. kueri langsung menggunakan semua indeks pada tabel sedangkan tampilan melakukan pemindaian tabel penuh. - person Madhusudhan Dollu; 13.12.2013
comment
di bagian internal fungsi, yang kondisinya berbeda berdasarkan parameternya. mereka akan ditambahkan secara dinamis dan permintaan akhir akan dieksekusi untuk mengambil hasilnya - person Madhusudhan Dollu; 13.12.2013