Tabel sementara secara efektif sama dengan tabel dalam memori berkat caching dan I/O asinkron, dan solusi tabel sementara tidak memerlukan overhead apa pun untuk mengonversi antara SQL dan PL/SQL.
Mengonfirmasi hasil
Membandingkan dua versi dengan RunStats, versi tabel sementara terlihat jauh lebih buruk. Semua sampah untuk versi tabel sementara di Run1, dan hanya sedikit memori tambahan untuk versi PL/SQL di Run2. Pada awalnya sepertinya PL/SQL harus menjadi pemenang yang jelas.
Type Name Run1 (temp) Run2 (PLSQL) Diff
----- -------------------------------- ------------ ------------ ------------
...
STAT physical read bytes 81,920 0 -81,920
STAT physical read total bytes 81,920 0 -81,920
LATCH cache buffers chains 104,663 462 -104,201
STAT session uga memory 445,488 681,016 235,528
STAT KTFB alloc space (block) 2,097,152 0 -2,097,152
STAT undo change vector size 2,350,188 0 -2,350,188
STAT redo size 2,804,516 0 -2,804,516
STAT temp space allocated (bytes) 12,582,912 0 -12,582,912
STAT table scan rows gotten 15,499,845 0 -15,499,845
STAT session pga memory 196,608 19,857,408 19,660,800
STAT logical read bytes from cache 299,958,272 0 -299,958,272
Tetapi pada akhirnya hanya waktu jam dinding yang penting. Langkah pemuatan dan kueri berjalan lebih cepat dengan tabel sementara.
Versi PL/SQL dapat ditingkatkan dengan mengganti BULK COLLECT
dengan cast(collect(test_o(MOD(a, 10), '' || MOD(a, 12))) as test_t) INTO t
. Tapi itu masih jauh lebih lambat daripada versi tabel sementara.
Bacaan yang Dioptimalkan
Membaca dari tabel sementara kecil hanya menggunakan cache buffer, yang ada di memori. Jalankan hanya bagian kueri beberapa kali, dan perhatikan bagaimana consistent gets from cache
(memori) meningkat saat physical reads cache
(disk) tetap sama.
select name, value
from v$sysstat
where name in ('db block gets from cache', 'consistent gets from cache',
'physical reads cache');
Tulisan yang Dioptimalkan
Idealnya tidak akan ada I/O fisik, terutama karena tabel sementara adalah ON COMMIT DELETE ROWS
. Dan sepertinya versi Oracle berikutnya akan memperkenalkan mekanisme seperti itu. Tapi itu tidak terlalu menjadi masalah dalam kasus ini, disk I/O tampaknya tidak memperlambat segalanya.
Jalankan langkah pemuatan beberapa kali, lalu jalankan select * from v$active_session_history order by sample_time desc;
. Sebagian besar I/O adalah BACKGROUND
, yang berarti tidak ada yang menunggu. Saya menganggap logika internal tabel sementara hanyalah salinan mekanisme DML biasa. Secara umum, data tabel baru mungkin perlu ditulis ke disk, jika di-commit. Oracle dapat mulai mengerjakannya, misalnya dengan memindahkan data dari buffer log ke disk, tetapi tidak perlu terburu-buru sampai ada COMMIT
yang sebenarnya. .
Ke mana perginya waktu PL/SQL?
Saya tidak tahu. Apakah ada beberapa sakelar konteks, atau satu konversi antara mesin SQL dan PL/SQL? Sejauh yang saya tahu tidak ada metrik yang tersedia yang menunjukkan waktu dihabiskan untuk beralih antara SQL dan PL/SQL.
Kita mungkin tidak pernah tahu persis mengapa kode PL/SQL lebih lambat. Saya tidak terlalu mengkhawatirkannya. Jawaban umumnya adalah, sebagian besar pekerjaan basis data harus dilakukan dalam SQL. Akan sangat masuk akal jika Oracle menghabiskan lebih banyak waktu untuk mengoptimalkan inti database mereka, SQL, daripada bahasa tambahan, PL/SQL.
Catatan tambahan
Untuk pengujian kinerja, sebaiknya hapus connect by
logika menjadi langkah terpisah. SQL itu adalah trik hebat untuk memuat data, tetapi bisa sangat lambat dan intensif sumber daya. Lebih realistis untuk memuat tabel sampel sekali dengan trik itu, lalu menyisipkan dari tabel itu.
Saya mencoba menggunakan fitur Oracle 12c baru, undo sementara, dan fitur 18c baru, tabel sementara pribadi. Tidak ada satu pun yang meningkatkan kinerja dibandingkan tabel sementara biasa.
Saya tidak akan bertaruh, tetapi saya dapat melihat cara bahwa hasilnya akan benar-benar berubah seiring dengan bertambahnya data. Buffer log dan cache buffer hanya bisa begitu besar. Dan akhirnya I/O latar belakang itu dapat menambah dan membanjiri beberapa proses, mengubah BACKGROUND
tunggu di FOREGROUND
tunggu. Di sisi lain, hanya ada begitu banyak memori PGA untuk solusi PL/SQL, dan kemudian semuanya macet.
Akhirnya, ini sebagian menegaskan skeptisisme saya terhadap "database dalam memori". Caching bukanlah hal baru, database telah melakukannya selama beberapa dekade.