Saya ingin memahami yang berikut ini.
Asumsikan bahwa saya memiliki kueri yang rumit dengan katakanlah gabungan 5 tabel grup dengan penjumlahan dan pesanan oleh.
Mengesampingkan semua optimasi untuk kueri itu sendiri, misalnya indeks, dll.
Apakah ada manfaat kinerja yang signifikan digunakan LIMIT
? Saya berasumsi bahwa semua permintaan (dan hasil) harus diproses sebelum LIMIT diterapkan, jadi menggunakan LIMIT untuk mengambil bagian dari hasil, apakah ini menawarkan perbaikan yang signifikan / nyata?
mysql
performance
join
Jim
sumber
sumber
LIMIT
meningkatkan efisiensi: Mengoptimalkan Pertanyaan LIMITJawaban:
Jika Anda ingin memanfaatkan
LIMIT
untuk meningkatkan kinerja, Anda perluLIMIT
sebelumnyaJOIN
Prinsip-prinsip ini bisa sangat bermanfaat jika Anda dapat mengaturnya.
Saya mempelajari konsep-konsep ini dengan menonton Video YouTube ini (dengarkan baik-baik melalui aksen Prancis)
Saya menggunakan konsep-konsep itu untuk menjawab pertanyaan StackOverflow yang sangat sulit tentang mendapatkan 40 artikel teratas dari beberapa tabel: 12 Mei 2011: Mengambil Satu Baris dari Bergabung dengan Tabel .
Dalam jawaban saya untuk pertanyaan itu (16 Mei 2011) , saya menulis pertanyaan berikut dan mengujinya secara menyeluruh:
Harap perhatikan baris dalam kueri dengan
LIMIT
Subquery ini terkubur dalam tiga level. Ini memungkinkan saya untuk menggunakan 40 artikel terakhir
LIMIT
. Kemudian, saya melakukan GABUNGAN yang diperlukan setelah itu.PELAJARAN YANG DIPELAJARI
LIMIT
subqueries di dalam mungkin tidak selalu menjadi jawaban karena kardinalitas indeks, konten data, dan ukuran set hasil dariLIMIT
. Jika Anda memiliki semua "bebek berturut-turut" (Perhatikan empat prinsip untuk kueri Anda), Anda dapat memperoleh hasil yang sangat bagus.LIMIT
dengan mengumpulkan kunci saja.sumber
(A [LEFT] JOIN B) LIMIT 100
setara dengan(A LIMIT 100) [LEFT] JOIN (B LIMIT 100)
? Di mana[LEFT] JOIN
berarti gabungan luar atau dalam(A LIMIT 100) [LEFT] JOIN B
. Idenya adalah menggunakanLIMIT
untuk menentukan ukuran hasil yang ditetapkan sedini mungkin. Saya juga menggunakanLEFT JOIN
bukanINNER JOIN
karenaLEFT JOIN
akan mempertahankan urutan tombol di sebelah kiri.(A LEFT JOIN B) GROUP BY A.pk LIMIT 100
biasanya dapat ditulis ulang sebagai(A LIMIT 100) LEFT JOIN B GROUP BY A.pk
(tidak ada INNER BERGABUNG di sini, dengan gabungan batin mereka tidak akan setara.) Contoh Rolando adalah kasus yang persis seperti itu.Ketika sebuah query dieksekusi, ia pertama-tama akan diterjemahkan ke dalam sebuah rencana yang terdiri dari beberapa operator. Ada dua tipe dasar operator: Blocking dan Non-Blocking. Operator Non-Blocking mengambil baris (atau beberapa baris) dari anak atau anak-anaknya untuk setiap baris yang diminta darinya. Operator Blocking di sisi lain harus membaca dan memproses seluruh baris set semua anak-anaknya sebelum dapat menghasilkan output apa pun.
Sortir adalah Operator Pemblokiran pada umumnya. Jadi pilih dengan pesanan tidak mendapat banyak manfaat dari batas. Namun, ada RDBMS yang dapat memanfaatkan algoritma pengurutan yang membutuhkan lebih sedikit memori dan lebih cepat ketika klausa batas disediakan. Dalam kasus ini cukup untuk hanya menyimpan baris n saat ini dan memindahkannya dari memori karena baris sebelumnya datang. Itu bisa menjadi keuntungan kinerja yang signifikan. Namun, saya tidak 100% yakin bahwa MySQL memiliki kemampuan itu.
Either way, bahkan batas-semacam masih perlu memproses seluruh baris input yang ditetapkan sebelum dapat menghasilkan baris output pertama. Meskipun algoritma ini, jika diterapkan, dapat mempercepat pengurutan, jika sisa kueri adalah bagian yang paling mahal, total waktu eksekusi tidak akan meningkat secara signifikan karena batas yang disediakan.
sumber
GROUP BY
berpotensi menyebabkan rencana yang berjalan tidak mengandung operator pemblokiran.Dalam kasus saya, saya bisa mengatakan Ya , bahkan jika saya (masih) tidak mengerti mengapa.
Catat waktu: 18 detik. Permintaan yang sama dengan LIMIT besar:
Lebih dari sepuluh kali lebih cepat !!!
MENJELASKAN memberikan hasil yang sama untuk kedua permintaan.
LIMIT harus mengganggu hanya untuk membatasi set hasil (yaitu, jika saya melakukan LIMIT 4, saya hanya mendapat 4 baris pertama dari set hasil di atas).
sumber
LIMIT
. Kueri pertama Anda berjalan dalam 18 detik memberikan hasil yang ditetapkan. Semua data dalam kueri ke-2 sudah di-cache di pool buffer InnoDB karena kueri pertama, Jadi tentu saja kueri ke-2 harus lebih cepat, Bahkan jika Anda me-restart mysql, jalankan kueri 1, restart mysql, dan jalankan ke-2 permintaan, Anda akan mendapatkan hasil yang sama. . Memiliki hasil yang lebih baikLIMIT
hanya dapat diperoleh dari melakukan: 1)LIMIT
sebelumnyaJOIN
, 2) LIMIT dalam urutanASC
atauDESC
.