Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Mengoptimalkan kueri mysql (suka/tidak suka)

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PHP/MySQL pencarian pengguna yang lebih baik

  2. MySQL mencocokkan karakter unicode dengan versi ascii

  3. masalah dengan utf8 di java

  4. PEMICU yang menyebabkan INSERT gagal? Bisa jadi?

  5. Bagaimana menjalankan perintah bash selama redirect <<EOF