Saat Anda membatasi jumlah baris yang akan dikembalikan oleh kueri SQL, biasanya digunakan dalam paging, ada dua metode untuk menentukan jumlah total catatan:
Metode 1
Sertakan SQL_CALC_FOUND_ROWS
opsi dalam yang asli SELECT
, dan kemudian dapatkan jumlah total baris dengan menjalankan SELECT FOUND_ROWS()
:
SELECT SQL_CALC_FOUND_ROWS * FROM table WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();
Metode 2
Jalankan kueri secara normal, lalu dapatkan jumlah total baris dengan menjalankan SELECT COUNT(*)
SELECT * FROM table WHERE id > 100 LIMIT 10;
SELECT COUNT(*) FROM table WHERE id > 100;
Metode mana yang terbaik / tercepat?
sumber
SQL_CALC_FOUND_ROWS
waktu lebih dari 20 detik; menggunakanCOUNT(*)
kueri terpisah membutuhkan waktu di bawah 5 detik (untuk kueri hitungan + hasil).SQL_CALC_FOUND_ROWS
akan lebih cepat, aku bertanya-tanya dalam situasi apa (jika ada) itu benar-benar adalah lebih cepat!tblA
,tblB
,tblC
,tblD
,tblY
MANA tblA.b = tblC.id DAN tblA.c = tblB.id DAN tblA.d = tblD.id DAN tblA.y = tblY.idid
) butuh 0,25 saja.FOUND_ROWS()
telah usang dalam MySQL 8.0.17. Lihat juga jawaban @ madhur-bhaiya.Saat memilih pendekatan "terbaik", pertimbangan yang lebih penting daripada kecepatan mungkin adalah pemeliharaan dan kebenaran kode Anda. Jika demikian, SQL_CALC_FOUND_ROWS lebih disukai karena Anda hanya perlu mempertahankan satu permintaan. Menggunakan satu kueri benar-benar menghalangi kemungkinan perbedaan halus antara kueri utama dan jumlah, yang dapat menyebabkan COUNT tidak akurat.
sumber
MySQL telah mulai
SQL_CALC_FOUND_ROWS
menghilangkan fungsionalitas dengan versi 8.0.17 dan seterusnya.Jadi, selalu lebih disukai untuk mempertimbangkan mengeksekusi kueri Anda dengan
LIMIT
, dan kemudian kueri kedua denganCOUNT(*)
dan tanpaLIMIT
menentukan apakah ada baris tambahan.Dari dokumen :
Juga,
SQL_CALC_FOUND_ROWS
telah diamati memiliki lebih banyak masalah secara umum, seperti yang dijelaskan dalam MySQL WL # 12615 :sumber
LOCK TABLES <tablename>
danUNLOCK TABLES
. Opsi ketiga dan (IMHO terbaik) adalah memikirkan kembali pagination. Silakan baca: mariadb.com/kb/en/library/pagination-optimizationMenurut artikel berikut: https://www.percona.com/blog/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/
Jika Anda memiliki INDEKS pada klausa tempat Anda (jika id diindeks pada kasus Anda), maka lebih baik untuk tidak menggunakan SQL_CALC_FOUND_ROWS dan menggunakan 2 kueri sebagai gantinya, tetapi jika Anda tidak memiliki indeks pada apa yang Anda masukkan dalam klausa mana Anda (id dalam kasus Anda) kemudian menggunakan SQL_CALC_FOUND_ROWS lebih efisien.
sumber
IMHO, alasan mengapa 2 pertanyaan
lebih cepat daripada menggunakan SQL_CALC_FOUND_ROWS
harus dilihat sebagai kasus tertentu.
Itu sebenarnya tergantung pada selektivitas klausa WHERE dibandingkan dengan selektivitas implisit yang setara dengan ORDER + LIMIT.
Seperti yang dikatakan oleh Arvids dalam komentar ( http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/#comment-1174394 ), fakta bahwa EXPLAIN menggunakan, atau tidak, tabel temporay, harus menjadi dasar yang baik untuk mengetahui apakah SCFR akan lebih cepat atau tidak.
Tetapi, seperti yang saya tambahkan ( http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/#comment-8166482 ), hasilnya benar-benar tergantung pada kasusnya. Untuk paginator tertentu, Anda bisa sampai pada kesimpulan bahwa “untuk 3 halaman pertama, gunakan 2 pertanyaan; untuk halaman-halaman berikut, gunakan SCFR ”!
sumber
Menghapus beberapa SQL yang tidak perlu dan kemudian
COUNT(*)
akan lebih cepat dariSQL_CALC_FOUND_ROWS
. Contoh:Kemudian hitung tanpa bagian yang tidak perlu:
sumber
Ada opsi lain yang bisa Anda tolak:
1.) Fungsi jendela akan mengembalikan ukuran aktual secara langsung (diuji dalam MariaDB):
2.) Berpikir di luar kotak, sebagian besar waktu pengguna tidak perlu mengetahui ukuran EXACT dari tabel, perkiraan seringkali cukup baik.
sumber