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

dapatkah itu dieksekusi lebih cepat dengan sejumlah besar data [MySQL]

Melihat EXPLAIN output, saya khawatir bahwa penggunaan subquery Anda telah mengakibatkan penggunaan indeks yang tidak optimal. Saya merasa (tanpa pembenaran apa pun - dan dalam hal ini saya mungkin salah) yang menulis ulang menggunakan JOIN mungkin mengarah ke kueri yang lebih optimal.

Untuk melakukan itu, kami perlu memahami apa yang dimaksudkan untuk dilakukan oleh kueri Anda. Akan membantu jika pertanyaan Anda telah mengartikulasikannya, tetapi setelah sedikit menggaruk-garuk kepala, saya memutuskan bahwa kueri Anda mencoba mengambil daftar semua kata kunci lain yang muncul di artikel mana pun yang berisi beberapa kata kunci tertentu, bersama dengan hitungan dari semua artikel di mana kata kunci tersebut muncul .

Sekarang mari kita buat ulang kueri secara bertahap:

  1. Ambil "artikel apa pun yang berisi beberapa kata kunci tertentu " (tidak khawatir tentang duplikat):

    SELECT ca2.article_id
    FROM
           career_article_keyword AS ca2
    WHERE
          ca2.keyword_id = 9;
    
  2. Ambil "semua kata kunci lain yang muncul di [di atas] "

    SELECT ca1.keyword_id
    FROM
           career_article_keyword AS ca1
      JOIN career_article_keyword AS ca2 ON (ca2.article_id = ca1.article_id)
    WHERE
          ca1.keyword_id <> 9
      AND ca2.keyword_id =  9
    GROUP BY ca1.keyword_id;
    
  3. Ambil "[yang di atas], bersama dengan jumlah semua artikel di mana kata kunci tersebut muncul "

    SELECT ca1.keyword_id, COUNT(DISTINCT ca0.article_id) AS cnt
    FROM
           career_article_keyword AS ca0
      JOIN career_article_keyword AS ca1 USING (keyword_id)
      JOIN career_article_keyword AS ca2 ON (ca2.article_id = ca1.article_id)
    WHERE
          ca1.keyword_id <> 9
      AND ca2.keyword_id =  9
    GROUP BY ca1.keyword_id
    ORDER BY cnt DESC;
    
  4. Terakhir, kami ingin menambahkan ke output kata kunci yang cocok itu sendiri dari career_keyword tabel:

    SELECT ck.keyword_id, ck.keyword, COUNT(DISTINCT ca0.article_id) AS cnt
    FROM
           career_keywords        AS ck 
      JOIN career_article_keyword AS ca0 USING (keyword_id)
      JOIN career_article_keyword AS ca1 USING (keyword_id)
      JOIN career_article_keyword AS ca2 ON (ca2.article_id = ca1.article_id)
    WHERE
          ca1.keyword_id <> 9
      AND ca2.keyword_id =  9
    GROUP BY ck.keyword_id -- equal to ca1.keyword_id due to join conditions
    ORDER BY cnt DESC;
    

Satu hal yang segera jelas adalah bahwa kueri asli Anda mereferensikan career_keywords dua kali, sedangkan kueri yang ditulis ulang ini merujuk tabel itu hanya sekali; ini saja mungkin menjelaskan perbedaan kinerja - coba hapus referensi kedua untuk itu (yaitu di mana ia muncul di subkueri pertama Anda), karena sepenuhnya berlebihan di sana.

Melihat kembali kueri ini, kita dapat melihat bahwa penggabungan sedang dilakukan pada kolom berikut:

  • career_keywords.keyword_id di ck JOIN ca0

    Tabel ini mendefinisikan PRIMARY KEY (`keyword_id`) , jadi ada indeks bagus yang bisa digunakan untuk bergabung ini.

  • career_article_keyword.article_id di ca1 JOIN ca2

    Tabel ini mendefinisikan UNIQUE KEY `article_id` (`article_id`,`keyword_id`) dan, karena article_id adalah kolom paling kiri dalam indeks ini, ada indeks bagus yang dapat digunakan untuk bergabung ini.

  • career_article_keyword.keyword_id di ck JOIN ca0 dan ca0 JOIN ca1

    Tidak ada indeks yang dapat digunakan untuk penggabungan ini:satu-satunya indeks yang ditentukan dalam tabel ini memiliki kolom lain, article_id di sebelah kiri keyword_id - jadi MySQL tidak dapat menemukan keyword_id entri dalam indeks tanpa terlebih dahulu mengetahui article_id . Saya sarankan Anda membuat indeks baru yang memiliki keyword_id sebagai kolom paling kiri.

    (Kebutuhan indeks ini sama-sama dapat dipastikan langsung dari melihat kueri asli Anda, di mana dua kueri terluar Anda melakukan penggabungan pada kolom itu.)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Skrip SQL - Apakah yang setara dengan #define ada?

  2. MYSQL - pilih 4 catatan pertama untuk setiap kategori dalam sebuah tabel

  3. Redirect beberapa url melalui database mysql?

  4. Bagaimana cara mengatur innodb_buffer_pool_size global?

  5. Bagaimana cara mengembalikan database mysql di XAMPP?