Cara mana untuk menghitung jumlah baris yang harus lebih cepat di MySQL?
Ini:
SELECT COUNT(*) FROM ... WHERE ...
Atau, alternatifnya:
SELECT 1 FROM ... WHERE ...
// and then count the results with a built-in function, e.g. in PHP mysql_num_rows()
Orang akan berpikir bahwa metode pertama harus lebih cepat, karena ini jelas merupakan wilayah database dan mesin database harus lebih cepat daripada orang lain saat menentukan hal-hal seperti ini secara internal.
mysql
performance
Franz
sumber
sumber
SELECT 1
dan tidakSELECT *
. Apakah ada bedanya?mysql_query()
, misalnya, seluruh rangkaian hasil dikirim ke PHP dari MySQL, apa pun yang Anda lakukan. lakukan dengan data itu.Jawaban:
Ketika Anda
COUNT(*)
mengambil indeks kolom hitung, jadi itu akan menjadi hasil terbaik. Mysql dengan mesin MyISAM sebenarnya menyimpan jumlah baris, tidak menghitung semua baris setiap kali Anda mencoba menghitung semua baris. (berdasarkan kolom kunci utama)Menggunakan PHP untuk menghitung baris tidak terlalu pintar, karena Anda harus mengirim data dari mysql ke php. Mengapa melakukannya ketika Anda dapat mencapai hal yang sama di sisi mysql?
Jika
COUNT(*)
lambat, Anda harus menjalankanEXPLAIN
kueri, dan memeriksa apakah indeks benar-benar digunakan, dan di mana mereka harus ditambahkan.Berikut ini bukan cara tercepat , tetapi ada kasus, di mana
COUNT(*)
tidak benar-benar cocok - ketika Anda mulai mengelompokkan hasil, Anda dapat mengalami masalah, di manaCOUNT
tidak benar-benar menghitung semua baris.Solusinya adalah
SQL_CALC_FOUND_ROWS
. Ini biasanya digunakan saat Anda memilih baris tetapi masih perlu mengetahui jumlah baris total (misalnya, untuk paging). Saat Anda memilih baris data, cukup tambahkanSQL_CALC_FOUND_ROWS
kata kunci setelah PILIH:Setelah Anda memilih baris yang dibutuhkan, Anda bisa mendapatkan hitungan dengan kueri tunggal ini:
FOUND_ROWS()
harus dipanggil segera setelah kueri pemilihan data.Kesimpulannya, semuanya sebenarnya tergantung pada berapa banyak entri yang Anda miliki dan apa yang ada di pernyataan WHERE. Anda harus benar-benar memperhatikan bagaimana indeks digunakan, ketika ada banyak baris (puluhan ribu, jutaan, dan lebih tinggi).
sumber
MyISAM
menyimpan jumlah baris. Mesin penyimpanan lain sepertiInnoDB
tidak menyimpan jumlah baris dan akan menghitung semua baris setiap saat .SELECT 1 FROM ... LIMIT 1
atauSELECT COUNT(*) FROM ...
?WHERE
klausul.SELECT COUNT(*) FROM ...
dapat memakan banyak waktu, tergantung pada apa yang harus dipindai (mis. Tabel yang sangat besar atau indeks jutaan / miliaran / triliunan baris).SELECT 1 FROM ... LIMIT 1
segera kembali karena Anda membatasinya ke baris pertama.Setelah berbicara dengan rekan satu tim saya, Ricardo memberi tahu kami bahwa cara yang lebih cepat adalah:
Tetapi Anda harus ingat bahwa hasilnya mungkin tidak tepat.
Anda juga dapat menggunakannya dari baris perintah:
Informasi lebih lanjut: http://dev.mysql.com/doc/refman/5.7/en/show-table-status.html
Dan Anda bisa menemukan pembahasan lengkapnya di mysqlperformanceblog
sumber
SHOW TABLE STATUS
(atau yang setaraSELECT
dalaminformation_schema
) itu cepat, tetapi tidak menanganiWHERE
klausa. Ini tepat untuk MyISAM, tetapi tidak tepat (terkadang dengan faktor 2) untuk InnoDB.Pertanyaan bagus, jawaban bagus. Inilah cara cepat untuk menggemakan hasil jika ada yang membaca halaman ini dan melewatkan bagian itu:
sumber
as count
?id
membingungkan pada pandangan pertama.Kueri ini (yang mirip dengan bayuah yang diposting ) menunjukkan ringkasan yang bagus dari semua tabel yang dihitung di dalam database: (versi sederhana dari prosedur tersimpan oleh Ivan Cachicatari yang sangat saya rekomendasikan).
Contoh:
sumber
information_schema
tidak sama dengan yang dikembalikan olehSELECT count(*) FROM
jika InnoDB digunakan. Jika Anda membutuhkan nilai yang ketat maka perlu diingat bahwa metode ini memberikan nilai yang ketat hanya dengan tabel MyISAM. Dengan InnoDB jumlah baris merupakan perkiraan kasar.Saya selalu mengerti bahwa di bawah ini akan memberi saya waktu respons tercepat.
sumber
SELECT 1 ...
akan kembali sebagai banyak baris sebagaiWHERE
danLIMIT
meminta, dan mereka semua akan "1".show table status like '<TABLE NAME>'
Ini akan jauh lebih cepat.WHERE
klausul. Dan, untuk InnoDB, itu hanya perkiraan.Jika Anda perlu menghitung seluruh rangkaian hasil, Anda dapat mengambil pendekatan berikut:
Ini biasanya tidak lebih cepat daripada menggunakan
COUNT
meskipun orang mungkin berpikir sebaliknya adalah kasusnya karena melakukan perhitungan secara internal dan tidak mengirim data kembali ke pengguna sehingga peningkatan kinerja dicurigai.Melakukan dua kueri ini bagus untuk penomoran halaman untuk mendapatkan total tetapi tidak secara khusus untuk menggunakan
WHERE
klausa.sumber
Saya melakukan beberapa tolok ukur untuk membandingkan waktu eksekusi
COUNT(*)
vsCOUNT(id)
(id adalah kunci utama dari tabel - diindeks).Jumlah percobaan: 10 * 1000 kueri
Hasil:
COUNT(*)
lebih cepat 7%LIHAT GRAFIK: benchmarkgraph
Saran saya adalah menggunakan:
SELECT COUNT(*) FROM table
sumber
COUNT(1)
, pasti menarik melihat beberapa benchmark disana ...Coba ini:
sumber
select count(*) from table_name
atau sesuatu yang lain. dba.stackexchange.com/questions/151769/…Mungkin Anda mungkin ingin mempertimbangkan untuk melakukan a
SELECT max(Id) - min(Id) + 1
. Ini hanya akan berfungsi jika Id Anda berurutan dan baris tidak dihapus. Namun itu sangat cepat.sumber
EXPLAIN SELECT id FROM ....
melakukan trik untuk saya. dan saya bisa melihat jumlah baris di bawahrows
kolom hasilnya.sumber
Saya menangani tabel untuk Pemerintah Jerman dengan kadang-kadang 60 juta catatan.
Dan kami perlu mengetahui berkali-kali jumlah baris.
Jadi kami programmer database memutuskan bahwa dalam setiap tabel adalah record satu selalu record di mana jumlah record disimpan. Kami memperbarui nomor ini, bergantung pada baris INSERT atau DELETE.
Kami mencoba semua cara lain. Sejauh ini cara tercepat.
sumber
Pernyataan hitungan (*) dengan kondisi di mana pada kunci utama mengembalikan jumlah baris jauh lebih cepat untuk saya menghindari pemindaian tabel penuh.
Ini jauh lebih cepat bagi saya daripada
sumber