Saya telah bekerja untuk perusahaan yang berbeda, dan saya perhatikan bahwa beberapa dari mereka lebih suka memiliki pandangan yang akan bergabung dengan sebuah meja dengan semua "kerabat" nya. Tetapi kemudian pada aplikasi beberapa kali, kita hanya perlu menggunakan 1 kolom saja.
Jadi apakah lebih cepat membuat pilihan sederhana, dan kemudian "bergabung" dengan kode sistem?
Sistem bisa berupa php, java, asp, bahasa apa pun yang terhubung ke database.
Jadi pertanyaannya adalah, apa yang lebih cepat dari Sisi Server (php, java, asp, ruby, python ...) ke database menjalankan satu permintaan yang mendapatkan semua yang kita butuhkan atau pergi dari sisi server ke database dan menjalankan permintaan yang hanya mendapatkan kolom dari satu tabel pada saat itu?
sumber
Jawaban:
Apa yang akan menjawab pertanyaan Anda adalah subjek JOIN DECOMPOSITION.
Menurut Halaman 209 dari Buku itu
Anda bisa menguraikan gabung dengan menjalankan beberapa kueri tabel tunggal alih-alih gabung multitable, dan kemudian melakukan gabung dalam aplikasi. Misalnya, alih-alih permintaan tunggal ini:
Anda dapat menjalankan kueri ini:
Kenapa kamu melakukan ini? Sekilas terlihat boros, karena Anda telah meningkatkan jumlah kueri tanpa mendapatkan balasan apa pun. Namun, restrukturisasi semacam itu sebenarnya dapat memberikan keuntungan kinerja yang signifikan:
mysql
sudah di-cache, aplikasi akan melewati kueri pertama. Jika Anda menemukan posting dengan ID 123, 567, atau 908 di cache, Anda dapat menghapusnya dariIN()
daftar. Tembolok kueri mungkin juga mendapat manfaat dari strategi ini. Jika hanya satu tabel yang sering berubah, penguraian gabungan dapat mengurangi jumlah cacat cache.IN()
daftar alih-alih bergabung memungkinkan MySQL mengurutkan ID baris dan mengambil baris lebih optimal daripada yang mungkin dilakukan dengan bergabung.Akibatnya, melakukan penggabungan dalam aplikasi bisa lebih efisien ketika Anda melakukan cache dan menggunakan kembali banyak data dari kueri sebelumnya, Anda mendistribusikan data di beberapa server, Anda mengganti
IN()
gabung dengan daftar, atau gabungan merujuk ke tabel yang sama beberapa kali.PENGAMATAN
Saya suka bulletpoint pertama karena InnoDB agak berat ketika crosscheck cache kueri.
Sep 05, 2012
: Apakah overhead dari seringnya permintaan cache tidak valid?Jun 07, 2014
: Mengapa query_cache_type dinonaktifkan secara default mulai dari MySQL 5.6?Sedangkan untuk bulletpoint terakhir, saya menulis posting kembali pada 11 Maret 2013 ( Apakah ada perbedaan eksekusi antara kondisi JOIN dan kondisi WHERE? ) Yang menjelaskan algoritma nested loop. Setelah membacanya, Anda akan melihat seberapa bagus dekomposisi gabungan.
Adapun semua poin lain dari buku ini , para pengembang benar-benar mencari kinerja sebagai garis bawah. Beberapa mengandalkan cara eksternal (di luar aplikasi) untuk peningkatan kinerja seperti menggunakan disk cepat, mendapatkan lebih banyak CPU / Core, menyetel mesin penyimpanan, dan menyetel file konfigurasi. Orang lain akan bekerja keras dan menulis kode yang lebih baik. Beberapa mungkin menggunakan pengkodean semua intelijen bisnis dalam Prosedur yang Disimpan tetapi masih belum menerapkan dekomposisi gabungan (Lihat Apa argumen yang menentang atau untuk menempatkan logika aplikasi di lapisan basis data? Bersama dengan postingan lain). Semuanya tergantung pada budaya dan toleransi masing-masing toko pengembang.
Beberapa mungkin puas dengan kinerja dan tidak menyentuh kode lagi. Lainnya tidak menyadari ada manfaat besar yang bisa dipetik orang jika mereka mencoba bergabung komposisi.
Bagi para pengembang yang bersedia ...
COBALAH !!!
sumber
Dalam Postgres (dan mungkin RDBMS pada tingkat yang sama, MySQL pada tingkat yang lebih rendah), lebih sedikit kueri yang hampir selalu jauh lebih cepat.
Overhead dari penguraian dan perencanaan beberapa kueri sudah lebih dari keuntungan yang mungkin dalam kebanyakan kasus.
Belum lagi pekerjaan tambahan yang harus dilakukan di klien, menggabungkan hasilnya, yang biasanya jauh lebih lambat. RDBMS berspesialisasi dalam tugas dan operasi semacam itu didasarkan pada tipe data asli. Tidak ada casting ke
text
dan kembali untuk hasil antara atau mengubah ke jenis asli klien, yang bahkan dapat menyebabkan hasil yang kurang benar (atau salah!). Pikirkan angka floating point ...Anda juga mentransfer lebih banyak data antara server DB dan klien. Ini mungkin diabaikan untuk tangan yang penuh dengan nilai, atau membuat perbedaan besar.
Jika beberapa kueri berarti beberapa round trip ke server database, Anda juga mengumpulkan beberapa kali latensi jaringan dan overhead transaksi, bahkan mungkin koneksi overhead. Kerugian besar.
Tergantung pada pengaturan Anda, latensi jaringan saja dapat memakan waktu lebih lama dari yang lainnya dengan perintah besarnya.
Pertanyaan terkait pada SO:
Mungkin ada titik balik untuk kueri berjalan sangat besar dan panjang karena transaksi mengumpulkan kunci pada baris DB di jalan. Kueri yang sangat besar dapat menahan banyak kunci untuk periode waktu yang lama yang dapat menyebabkan gesekan dengan permintaan bersamaan .
sumber
returns lots of redundant data for "parent" table
: Mengapa Anda mengembalikan data yang berlebihan? Hanya kembalikan data yang Anda butuhkan.