Dalam hal kinerja, subquery yang berkorelasi tersebut dapat memakan makan siang Anda. Dan makan kotak makan Anda juga, untuk set besar, karena cara MySQL memprosesnya. Masing-masing subkueri tersebut dieksekusi untuk setiap baris yang dikembalikan dalam kueri luar. Dan itu bisa menjadi sangat mahal untuk set besar.
Pendekatan alternatif adalah dengan menggunakan tampilan inline untuk mewujudkan suka dan tidak suka untuk semua konten, dan kemudian melakukan operasi gabungan untuk itu.
Tapi, pendekatan ini bisa mahal juga, terutama ketika Anda hanya membutuhkan suara "dihitung" hanya untuk beberapa baris konten, dari bazillion baris. Seringkali, ada predikat dari kueri luar yang juga dapat dimasukkan ke dalam tampilan sebaris, untuk membatasi jumlah baris yang perlu diperiksa dan dikembalikan.
Kami ingin menggunakan OUTER join ke tampilan inline itu, sehingga mengembalikan hasil yang setara dengan kueri Anda; mengembalikan baris dari content
ketika tidak ada baris yang cocok di vote
tabel.
SELECT [... BUNCH OF FIELDS ...]
, COALESCE(v.likes,0) AS likes
, COALESCE(v.dislikes,0) AS dislikes
, COALESCE(v.myvote,'.Constants::NO_VOTE.') AS myvote
FROM content c
LEFT
JOIN ( SELECT vt.cId
, SUM(vt.vote = '.Constants::LIKE.') AS likes
, SUM(vt.vote = '.Constants::DISLIKE.') AS dislikes
, MAX(IF(vt.userId = '.USER_ID.',vt.vote,NULL)) AS myvote
FROM votes vt
GROUP
BY vt.cId
) v
ON v.cId = c.contentId
[... OTHER STUFF ... ]
Perhatikan bahwa kueri tampilan sebaris (alias sebagai v
) akan melihat SETIAP baris dari votes
meja. Jika Anda hanya membutuhkan subset, maka pertimbangkan untuk menambahkan predikat yang sesuai (baik dalam klausa WHERE atau sebagai JOIN ke tabel lain). Tidak ada indikasi dari [... OTHER STUFF ...]
dalam kueri Anda apakah itu mengembalikan hanya beberapa baris dari content
atau jika Anda membutuhkan semua baris karena Anda memesan dengan likes
, dll.
Untuk sejumlah kecil baris yang dipilih dari content
tabel, menggunakan subkueri yang berkorelasi (seperti dalam kueri Anda) sebenarnya bisa lebih cepat daripada mewujudkan tampilan sebaris yang besar dan melakukan operasi gabungan terhadapnya.
Oh... dan untuk kedua kueri, tak perlu dikatakan bahwa indeks yang sesuai pada votes
tabel dengan kolom utama cId
akan menguntungkan kinerja. Untuk tampilan sebaris, Anda tidak ingin overhead MySQL harus melakukan filesort
operasi pada semua baris tersebut untuk melakukan GROUP BY. Dan untuk subkueri yang berkorelasi, Anda ingin mereka menggunakan pemindaian rentang indeks, bukan pemindaian penuh.