Ada situasi yang mengharuskan memiliki kueri sangat besar bergabung dengan beberapa tabel bersama dengan pernyataan sub pilih di dalamnya untuk menghasilkan hasil yang diinginkan.
Pertanyaan saya adalah, haruskah kita mempertimbangkan menggunakan beberapa kueri yang lebih kecil dan membawa operasi logis ke dalam lapisan aplikasi dengan meminta DB dalam lebih dari satu panggilan atau lebih baik memiliki semuanya sekaligus?
Sebagai contoh, pertimbangkan pertanyaan berikut:
SELECT *
FROM `users`
WHERE `user_id` IN (SELECT f2.`friend_user_id`
FROM `friends` AS f1
INNER JOIN `friends` AS f2
ON f1.`friend_user_id` = f2.`user_id`
WHERE f2.`is_page` = 0
AND f1.`user_id` = "%1$d"
AND f2.`friend_user_id` != "%1$d"
AND f2.`friend_user_id` NOT IN (SELECT `friend_user_id`
FROM `friends`
WHERE `user_id` = "%1$d"))
AND `user_id` NOT IN (SELECT `user_id`
FROM `friend_requests`
WHERE `friend_user_id` = "%1$d")
AND `user_image` IS NOT NULL
ORDER BY RAND()
LIMIT %2$d
Apa cara terbaik untuk melakukannya?
sumber
Sebagai seseorang yang harus mendukung / membersihkan pertanyaan besar dan rumit ini, saya akan mengatakan itu jauh lebih baik untuk memecah mereka menjadi beberapa potongan kecil yang mudah dimengerti. Ini tidak selalu lebih baik dari sudut pandang kinerja, tetapi Anda setidaknya memberikan SQL kesempatan yang lebih baik untuk datang dengan rencana permintaan yang bagus.
Buat hidup lebih mudah pada orang-orang yang mengikuti Anda, dan mereka akan mengatakan hal-hal baik tentang Anda. Buat itu sulit bagi mereka dan mereka akan mengutuk Anda.
sumber
2 sen saya pada 2 kata kunci, performa dan skalabilitas kata kunci:
Query-Performance: Paralelisme SQL Server sudah melakukan pekerjaan yang sangat baik memecah query menjadi pencarian multi-threaded jadi saya tidak yakin berapa banyak peningkatan kinerja query yang akan Anda lihat dengan melakukannya untuk SQL Server. Anda harus melihat pada rencana eksekusi untuk melihat seberapa jauh tingkat paralelisme yang Anda dapatkan ketika Anda menjalankannya dan membandingkan hasil keduanya. Jika Anda akhirnya harus menggunakan petunjuk kueri untuk mendapatkan kinerja yang sama atau lebih baik, maka IMO tidak layak karena petunjuk kueri mungkin tidak akan optimal nanti.
Skalabilitas: Membaca kueri mungkin lebih mudah seperti yang dinyatakan datagod, dan memecahnya menjadi kueri yang terpisah masuk akal jika Anda dapat menggunakan kueri baru di area lain juga, tetapi jika Anda tidak akan menggunakannya untuk panggilan lain juga, maka itu akan menjadi procs yang lebih disimpan untuk mengelola untuk 1 tugas, dan IMO tidak akan berkontribusi pada skalabilitas.
sumber
LIMIT
Terkadang, tidak ada pilihan selain untuk memecah kueri besar / kompleks menjadi kueri kecil. Cara terbaik untuk menentukan itu adalah dengan menggunakan
EXPLAIN
pernyataan denganSELECT
pernyataan itu. Jumlah jejak / pindaian yang akan dilakukan db Anda untuk mengambil data Anda adalah produk dari nilai "baris" yang dikembalikan olehEXPLAIN
kueri Anda . Dalam kasus kami, kami memiliki kueri yang menggabungkan 10 tabel. Untuk catatan tertentu, jejak berjumlah 409M yang membuat blog DB kami dan mendorong penggunaan CPU kami dari server DB kami lebih dari 300%. Kami dapat mengambil informasi yang sama dengan memecah kueri jauh lebih cepat.Jadi, singkatnya, dalam beberapa kasus memecah permintaan yang kompleks / besar masuk akal tetapi dalam kasus lain hal itu dapat menyebabkan banyak masalah kinerja atau pemeliharaan dan ini harus diperlakukan berdasarkan kasus per kasus.
sumber