Skalabilitas adalah tentang pra-komputasi, menyebarkan, atau memilah-milah pekerjaan yang berulang ke hal-hal penting, untuk meminimalkan penggunaan sumber daya per unit kerja. Untuk menskalakan dengan baik, Anda tidak melakukan apa pun yang tidak perlu dalam volume, dan hal-hal yang sebenarnya Anda lakukan Anda pastikan dilakukan seefisien mungkin.
Dalam konteks tersebut, tentu saja menggabungkan dua sumber data terpisah relatif lambat, setidaknya dibandingkan dengan tidak menggabungkannya, karena itu pekerjaan yang perlu Anda lakukan langsung pada titik di mana pengguna memintanya.
Tapi ingat alternatifnya tidak lagi memiliki dua bagian data yang terpisah sama sekali; Anda harus meletakkan dua titik data yang berbeda dalam catatan yang sama. Anda tidak dapat menggabungkan dua bagian data yang berbeda tanpa konsekuensi di suatu tempat, jadi pastikan Anda memahami kompromi.
Kabar baiknya adalah database relasional modern bisa digabungkan dengan baik . Anda tidak boleh menganggap join lambat dengan database yang bagus digunakan dengan baik. Ada sejumlah cara ramah skalabilitas untuk mengambil gabungan mentah dan membuatnya lebih cepat:
- Bergabunglah dengan kunci pengganti (kolom autonumer / identitas) daripada kunci alami. Ini berarti perbandingan yang lebih kecil (dan karenanya lebih cepat) selama operasi penggabungan
- Indeks
- Tampilan terwujud / terindeks (anggap ini sebagai gabungan yang dihitung sebelumnya atau de-normalisasi terkelola )
- Kolom yang dihitung. Anda dapat menggunakan ini untuk melakukan hash atau melakukan prapenghitungan kolom kunci gabungan, sehingga perbandingan rumit untuk gabungan sekarang jauh lebih kecil dan berpotensi diindeks sebelumnya.
- Partisi tabel (membantu kumpulan data besar dengan menyebarkan beban ke beberapa disk, atau membatasi apa yang mungkin tadinya pemindaian tabel ke pemindaian partisi)
- OLAP (menghitung sebelumnya hasil dari jenis kueri / gabungan tertentu. Ini tidak sepenuhnya benar, tetapi Anda dapat menganggapnya sebagai denormalisasi umum )
- Replikasi, Grup Ketersediaan, Pengiriman log, atau mekanisme lain yang memungkinkan beberapa server menjawab kueri baca untuk database yang sama, dan dengan demikian menskalakan beban kerja Anda di antara beberapa server.
- Gunakan lapisan caching seperti Redis untuk menghindari menjalankan kembali kueri yang membutuhkan gabungan yang rumit.
Saya akan melangkah lebih jauh dengan mengatakan alasan utama database relasional ada sama sekali adalah untuk memungkinkan Anda bergabung secara efisien * . Ini tentunya bukan hanya untuk menyimpan data terstruktur (Anda dapat melakukannya dengan konstruksi file datar seperti csv atau xml). Beberapa opsi yang saya cantumkan bahkan akan memungkinkan Anda sepenuhnya membangun gabungan Anda terlebih dahulu, sehingga hasilnya sudah selesai sebelum Anda mengeluarkan kueri - sama seperti jika Anda telah mendenormalisasi data (memang dengan biaya operasi tulis yang lebih lambat).
Jika Anda memiliki gabungan yang lambat, Anda mungkin tidak menggunakan database Anda dengan benar.
De-normalisasi harus dilakukan hanya setelah teknik lain ini gagal. Dan satu-satunya cara Anda dapat benar-benar menilai "kegagalan" adalah dengan menetapkan tujuan kinerja yang berarti dan mengukurnya dengan tujuan tersebut. Jika Anda belum mengukur, terlalu dini untuk memikirkan de-normalisasi.
* Artinya, ada sebagai entitas yang berbeda dari kumpulan tabel belaka. Alasan tambahan untuk rdbms yang sebenarnya adalah akses bersamaan yang aman.
Gabungan bisa lebih lambat daripada menghindarinya melalui de-normalisasi tetapi jika digunakan dengan benar (bergabung pada kolom dengan indeks yang sesuai dan seterusnya) mereka tidak lambat secara inheren .
De-normalisasi adalah salah satu dari banyak teknik pengoptimalan yang dapat Anda pertimbangkan jika skema database yang dirancang dengan baik menunjukkan masalah performa.
sumber
Artikel mengatakan bahwa mereka lambat jika dibandingkan dengan tidak adanya gabungan. ini dapat dicapai dengan denormalisasi. jadi ada trade off antara kecepatan dan normalisasi. jangan lupa juga tentang pengoptimalan prematur :)
sumber
Pertama-tama, raison d'etre (alasan keberadaan) database relasional adalah untuk dapat memodelkan hubungan antar entitas. Gabungan hanyalah mekanisme yang digunakan untuk melintasi hubungan tersebut. Mereka pasti datang dengan biaya nominal, tetapi tanpa gabungan, sebenarnya tidak ada alasan untuk memiliki database relasional.
Dalam dunia akademis kita mempelajari hal-hal seperti berbagai bentuk normal (1, 2, 3, Boyce-Codd, dll.), Dan kita belajar tentang berbagai jenis kunci (primer, asing, alternatif, unik, dll.) Dan caranya hal-hal ini cocok untuk merancang database. Dan kami mempelajari dasar-dasar SQL serta memanipulasi baik struktur maupun data (DDL & DML).
Di dunia korporat, banyak konstruksi akademis ternyata secara substansial kurang layak daripada yang selama ini kita yakini. Contoh sempurna adalah gagasan tentang kunci utama. Secara akademis, atribut (atau kumpulan atribut) itulah yang secara unik mengidentifikasi satu baris dalam tabel. Jadi di banyak domain masalah, kunci utama akademik yang tepat adalah gabungan dari 3 atau 4 atribut. Namun, hampir semua orang di dunia korporat modern menggunakan bilangan bulat berurutan yang dihasilkan otomatis sebagai kunci utama tabel. Mengapa? Dua alasan. Yang pertama adalah karena membuat model jauh lebih bersih saat Anda memigrasi FK di semua tempat. Yang kedua, dan paling erat dengan pertanyaan ini, adalah bahwa mengambil data melalui gabungan lebih cepat dan lebih efisien pada satu bilangan bulat daripada pada 4 kolom varchar (seperti yang telah disebutkan oleh beberapa orang).
Mari kita gali lebih dalam sekarang menjadi dua subtipe spesifik dari database dunia nyata. Jenis pertama adalah database transaksional. Ini adalah dasar bagi banyak e-niaga atau aplikasi manajemen konten yang menggerakkan situs modern. Dengan DB transaksi, Anda sangat mengoptimalkan "throughput transaksi". Sebagian besar aplikasi perdagangan atau konten harus menyeimbangkan kinerja kueri (dari tabel tertentu) dengan kinerja penyisipan (di tabel lain), meskipun setiap aplikasi akan memiliki masalah unik yang didorong oleh bisnis untuk dipecahkan.
Jenis kedua dari database dunia nyata adalah database pelaporan. Ini digunakan hampir secara eksklusif untuk menggabungkan data bisnis dan untuk menghasilkan laporan bisnis yang bermakna. Mereka biasanya dibentuk berbeda dari database transaksi tempat data dibuat dan mereka sangat dioptimalkan untuk kecepatan pemuatan data massal (ETL) dan kinerja kueri dengan kumpulan data yang besar atau kompleks.
Dalam setiap kasus, pengembang atau DBA perlu menyeimbangkan fungsionalitas dan kurva kinerja dengan hati-hati, dan ada banyak trik peningkatan kinerja di kedua sisi persamaan. Di Oracle, Anda dapat melakukan apa yang disebut "menjelaskan rencana" sehingga Anda dapat melihat secara spesifik bagaimana kueri diurai dan dijalankan. Anda ingin memaksimalkan penggunaan indeks yang tepat dari DB. Satu benar-benar tidak-tidak buruk adalah menempatkan fungsi di klausa where dari kueri. Setiap kali Anda melakukannya, Anda menjamin bahwa Oracle tidak akan menggunakan indeks apa pun pada kolom tersebut dan kemungkinan besar Anda akan melihat pemindaian tabel penuh atau sebagian dalam paket penjelasan. Itu hanyalah satu contoh spesifik tentang bagaimana kueri dapat ditulis yang akhirnya menjadi lambat, dan tidak ada hubungannya dengan gabungan.
Dan saat kita berbicara tentang pemindaian tabel, mereka jelas memengaruhi kecepatan kueri secara proporsional dengan ukuran tabel. Pemindaian tabel lengkap dari 100 baris bahkan tidak terlihat. Jalankan kueri yang sama pada tabel dengan 100 juta baris, dan Anda harus kembali minggu depan untuk mengembalikannya.
Mari kita bicara tentang normalisasi sebentar. Ini adalah topik akademis positif lainnya yang bisa membuat Anda stres. Sebagian besar waktu ketika kita berbicara tentang normalisasi yang kita maksud adalah penghapusan data duplikat dengan memasukkannya ke dalam tabelnya sendiri dan memigrasi FK. Orang biasanya melewatkan seluruh hal ketergantungan yang dijelaskan oleh 2NF dan 3NF. Namun dalam kasus ekstrim, tentu saja mungkin untuk memiliki basis data BCNF sempurna yang sangat besar dan lengkap untuk menulis kode karena itu sangat dinormalisasi.
Jadi di mana kita menyeimbangkan? Tidak ada satu pun jawaban terbaik. Semua jawaban yang lebih baik cenderung berupa kompromi antara kemudahan pemeliharaan struktur, kemudahan pemeliharaan data, dan kemudahan pembuatan / pemeliharaan kode. Secara umum, semakin sedikit duplikasi data, semakin baik.
Jadi mengapa penggabungan terkadang lambat? Terkadang itu desain relasional yang buruk. Terkadang pengindeksan tidak efektif. Terkadang ini masalah volume data. Terkadang itu adalah pertanyaan yang ditulis dengan sangat buruk.
Maaf untuk jawaban yang bertele-tele seperti itu, tetapi saya merasa terdorong untuk memberikan konteks yang lebih kecil di sekitar komentar saya daripada hanya memberikan tanggapan 4-peluru.
sumber
Orang-orang dengan database berukuran terrabyte masih menggunakan join, jika mereka bisa membuatnya bekerja dengan baik maka Anda juga bisa.
Ada banyak alasan untuk tidak melakukan denomalisasi. Pertama, kecepatan kueri pemilihan bukan satu-satunya atau bahkan perhatian utama dengan database. Integritas data adalah perhatian pertama. Jika Anda melakukan denormalisasi, Anda harus menerapkan teknik untuk menjaga agar data tidak dinormalisasi saat data induk berubah. Jadi misalkan Anda menyimpan nama klien di semua tabel daripada bergabung ke tabel klien di client_Id. Sekarang ketika nama klien berubah (100% kemungkinan beberapa nama klien akan berubah seiring waktu), sekarang Anda perlu memperbarui semua catatan anak untuk mencerminkan perubahan itu. Jika Anda melakukan ini dengan pembaruan bertingkat dan Anda memiliki sejuta catatan turunan, seberapa cepat Anda mengira hal itu akan terjadi dan berapa banyak pengguna yang akan mengalami masalah penguncian dan penundaan dalam pekerjaan mereka saat itu terjadi? Lebih lanjut kebanyakan orang yang melakukan denormalisasi karena "
Denormalisasi adalah proses kompleks yang membutuhkan pemahaman menyeluruh tentang kinerja dan integritas database jika dilakukan dengan benar. Jangan mencoba mengubah normalisasi kecuali Anda memiliki keahlian seperti itu pada staf.
Bergabung cukup cepat jika Anda melakukan beberapa hal. Pertama gunakan kunci suggorgate, int bergabung hampir selalu yang tercepat bergabung. Kedua, selalu indeks kunci asing. Gunakan tabel turunan atau gabungkan ketentuan untuk membuat kumpulan data yang lebih kecil untuk difilter. Jika Anda memiliki database besar yang sangat kompleks, maka rekrut orang database profesional dengan pengalaman dalam membuat partisi dan mengelola database besar. Ada banyak teknik untuk meningkatkan kinerja tanpa menghilangkan gabungan.
Jika Anda hanya membutuhkan kemampuan kueri, ya Anda dapat merancang gudang data yang dapat didenormalisasi dan diisi melalui alat ETL (dioptimalkan untuk kecepatan), bukan entri data pengguna.
sumber
Bergabung lambat jika
Jadi, benar, semakin besar kumpulan data Anda, semakin banyak pemrosesan yang Anda perlukan untuk kueri, tetapi memeriksa dan mengerjakan tiga opsi pertama di atas sering kali akan menghasilkan hasil yang bagus.
Sumber Anda memberikan denormalisasi sebagai opsi. Ini bagus hanya selama Anda sudah kehabisan alternatif yang lebih baik.
sumber
Gabungan bisa lambat jika sebagian besar rekaman dari setiap sisi perlu dipindai.
Seperti ini:
Bahkan jika indeks ditentukan
account_customer
, semua rekaman dari yang terakhir masih perlu dipindai.Untuk daftar kueri ini, pengoptimal yang layak mungkin tidak akan mempertimbangkan jalur akses indeks, melakukan a
HASH JOIN
atau aMERGE JOIN
sebagai gantinya.Perhatikan bahwa untuk kueri seperti ini:
gabungan kemungkinan besar akan cepat: pertama, indeks pada
customer_last_name
akan digunakan untuk memfilter semua Stellphlug (yang tentu saja tidak terlalu banyak), kemudian pemindaian indeksaccount_customer
akan dikeluarkan untuk setiap Stellphlug untuk menemukan transaksinya.Terlepas dari kenyataan bahwa ini bisa menjadi miliaran catatan
accounts
dancustomers
, hanya sedikit yang benar-benar perlu dipindai.sumber
accounts(account_customer)
sebagian besar RDBMS akan menggunakan indeks tersebut untuk mengetahui dengan tepat baris mana daricustomers
database yang perlu dipindai.HASH JOIN
akan jauh lebih cepat sehingga itulah yang akan digunakan kecuali di semua database utama kecualiMySQL
, yang hanya akancustomers
memimpin dalam loop bersarang (karena ukurannya lebih kecil)Joins are fast.
Gabungan harus dianggap sebagai praktik standar dengan skema database yang dinormalisasi dengan benar. Gabungan memungkinkan Anda untuk bergabung dengan kelompok data yang berbeda dengan cara yang berarti. Jangan takut bergabung.Peringatannya adalah Anda harus memahami normalisasi, penggabungan, dan penggunaan indeks yang tepat.
Waspadalah terhadap pengoptimalan prematur, karena kegagalan nomor satu dari semua proyek pengembangan adalah memenuhi tenggat waktu. Setelah Anda menyelesaikan proyek, dan Anda memahami pengorbanannya, Anda dapat melanggar aturan jika Anda dapat membenarkannya.
Memang benar bahwa kinerja gabungan menurun secara non-linier seiring dengan meningkatnya ukuran kumpulan data. Oleh karena itu, ini tidak menskalakan sebaik kueri tabel tunggal, tetapi masih melakukan skala.
Benar juga bahwa seekor burung terbang lebih cepat tanpa sayap, tetapi hanya lurus ke bawah.
sumber
Penggabungan memang memerlukan pemrosesan ekstra karena mereka harus mencari lebih banyak file dan lebih banyak indeks untuk "menggabungkan" data bersama. Namun, "kumpulan data yang sangat besar" semuanya relatif. Apa definisi besar? Dalam kasus GABUNG, saya pikir ini adalah referensi untuk kumpulan hasil yang besar, bukan keseluruhan dataset.
Sebagian besar database bisa sangat cepat memproses kueri yang memilih 5 catatan dari tabel utama dan menggabungkan 5 catatan dari tabel terkait untuk setiap catatan (dengan asumsi indeks yang benar ada). Tabel ini masing-masing dapat memiliki ratusan juta rekaman, atau bahkan miliaran.
Begitu kumpulan hasil Anda mulai berkembang, segalanya akan melambat. Menggunakan contoh yang sama, jika tabel utama menghasilkan 100 ribu rekaman, maka akan ada 500 ribu rekaman "bergabung" yang perlu ditemukan. Hanya menarik data sebanyak itu dari database dengan menambahkan penundaan.
Jangan hindari JOIN, cukup ketahuilah bahwa Anda mungkin perlu mengoptimalkan / denormalisasi saat set data menjadi "sangat besar".
sumber
Juga dari artikel yang Anda kutip:
dan
dan
Artikel tersebut membahas mega-situs seperti Ebay. Pada tingkat penggunaan itu, Anda mungkin harus mempertimbangkan sesuatu selain manajemen database relasional vanilla biasa. Namun dalam perjalanan bisnis "normal" (aplikasi dengan ribuan pengguna dan jutaan catatan), pendekatan yang lebih mahal dan rawan kesalahan itu berlebihan.
sumber
Gabungan dianggap sebagai kekuatan yang berlawanan dengan skalabilitas karena mereka biasanya menjadi penghambat dan tidak dapat dengan mudah didistribusikan atau diparalelkan.
sumber
Tabel yang dirancang dengan benar yang berisi dengan indikasi yang tepat dan kueri yang ditulis dengan benar tidak selalu lambat. Di mana pun Anda mendengar itu:
tidak tahu apa yang mereka bicarakan !!! Kebanyakan penggabungan akan berlangsung sangat cepat. Jika Anda harus menggabungkan banyak baris sekaligus, Anda mungkin menerima pukulan dibandingkan dengan tabel yang didenormalisasi, tetapi itu kembali ke tabel yang dirancang dengan benar, tahu kapan harus mendenormalisasi dan kapan tidak. dalam sistem pelaporan yang berat, pisahkan data dalam tabel yang didenormalisasi untuk laporan, atau bahkan buat gudang data. Dalam sistem berat transaksional menormalkan tabel.
sumber
Jumlah data sementara yang dihasilkan bisa sangat besar berdasarkan gabungannya.
Misalnya, satu database di sini di tempat kerja memiliki fungsi pencarian umum di mana semua bidang bersifat opsional. Rutin pencarian melakukan penggabungan di setiap meja sebelum pencarian dimulai. Ini bekerja dengan baik pada awalnya. Tapi, sekarang tabel utama memiliki lebih dari 10 juta baris ... tidak terlalu banyak. Pencarian sekarang membutuhkan waktu 30 menit atau lebih.
Saya ditugaskan untuk mengoptimalkan prosedur pencarian yang tersimpan.
Hal pertama yang saya lakukan adalah jika salah satu bidang dari tabel utama sedang dicari, saya melakukan pemilihan ke tabel temp pada bidang tersebut saja. LALU, saya menggabungkan semua tabel dengan tabel suhu itu sebelum melakukan pencarian selanjutnya. Pencarian dengan salah satu bidang tabel utama sekarang membutuhkan waktu kurang dari 10 detik.
Jika tidak ada bidang tabel utama yang mulai dicari, saya melakukan pengoptimalan serupa untuk tabel lain. Setelah saya selesai, tidak ada pencarian yang membutuhkan waktu lebih dari 30 detik dengan sebagian besar di bawah 10.
Pemanfaatan CPU dari server SQL juga turun.
sumber
Sementara penggabungan (mungkin karena desain yang dinormalisasi) jelas bisa lebih lambat untuk pengambilan data daripada membaca dari satu tabel, database yang didenormalisasi bisa lambat untuk operasi pembuatan / pembaruan data karena footprint dari keseluruhan transaksi tidak akan minimal.
Dalam database yang dinormalisasi, sepotong data hanya akan berada di satu tempat, jadi footprint untuk pembaruan akan seminimal mungkin. Dalam database yang didenormalisasi, ada kemungkinan bahwa kolom yang sama di beberapa baris atau di seluruh tabel harus diperbarui, yang berarti footprint akan lebih besar dan kemungkinan penguncian dan kebuntuan dapat meningkat.
sumber
Ya, memilih baris dari satu tabel yang didenormalisasi (dengan asumsi indeks yang layak untuk kueri Anda) mungkin lebih cepat daripada memilih baris yang dibuat dari penggabungan beberapa tabel, terutama jika gabungan tidak memiliki indeks yang efisien yang tersedia.
Contoh-contoh yang dikutip dalam artikel - Flickr dan eBay - adalah kasus-kasus luar biasa IMO, jadi dapatkan (dan pantas) tanggapan yang luar biasa. Penulis secara khusus menyebutkan kurangnya RI dan tingkat duplikasi data dalam artikel tersebut.
Sebagian besar aplikasi - sekali lagi, IMO - mendapat manfaat dari validasi & pengurangan duplikasi yang disediakan oleh RDBMS.
sumber
Mereka bisa lambat jika dilakukan dengan sembrono. Misalnya, jika Anda melakukan 'pilih *' saat bergabung, Anda mungkin memerlukan waktu beberapa saat untuk mendapatkan barang kembali. Namun, jika Anda dengan hati-hati memilih kolom apa yang akan dikembalikan dari setiap tabel, dan dengan indeks yang tepat pada tempatnya, seharusnya tidak ada masalah.
sumber