Semua orang tahu bahwa, dalam tabel yang menggunakan InnoDB sebagai mesin, kueri seperti SELECT COUNT(*) FROM mytable
sangat tidak eksak dan sangat lambat, terutama ketika tabel semakin besar dan ada penyisipan / penghapusan baris konstan saat query dijalankan.
Seperti yang saya pahami, InnoDB tidak menyimpan jumlah baris dalam variabel internal, yang merupakan alasan untuk masalah ini.
Pertanyaan saya adalah: Mengapa demikian? Akankah sangat sulit untuk menyimpan informasi seperti itu? Ini informasi penting untuk diketahui dalam banyak situasi. Satu-satunya kesulitan yang saya lihat apakah penghitungan internal seperti itu akan dilaksanakan adalah ketika transaksi terlibat: jika transaksi tidak dikomit, apakah Anda menghitung baris yang dimasukkan atau tidak?
PS: Saya bukan ahli tentang DB, saya hanya seseorang yang memiliki MySQL sebagai hobi sederhana. Jadi jika saya hanya menanyakan sesuatu yang bodoh, jangan terlalu kritis: D.
SELECT COUNT(*) FROM ...
sangat tepat. Jika Anda mau, phpMyAdmin dapat dikonfigurasi untuk selalu menggunakan jumlah baris yang tepat dengan mengorbankan kecepatan. Info lebih lanjut: stackoverflow.com/questions/11926259/…Jawaban:
Saya setuju dengan @RemusRusanu (+1 untuk jawabannya)
SELECT COUNT(*) FROM mydb.mytable
di InnoDB berperilaku seperti seharusnya mesin penyimpanan transaksional. Bandingkan dengan MyISAM.MyISAM
Jika
mydb.mytable
adalah tabel MyISAM, meluncurkanSELECT COUNT(*) FROM mydb.mytable;
seperti menjalankanSELECT table_rows FROM information_schema.table WHERE table_schema = 'mydb' AND table_name = 'mytable';
. Ini memicu pencarian cepat dari jumlah baris di header tabel MyISAM.InnoDB
Jika
mydb.mytable
tabel InnoDB, Anda mendapatkan hodge-podge hal-hal yang terjadi. Anda memiliki MVCC yang sedang berlangsung, mengatur hal-hal berikut:Meminta InnoDB untuk menghitung tabel membutuhkan navigasi melalui hal-hal yang tidak menyenangkan ini. Faktanya, seseorang tidak pernah benar-benar tahu jika
SELECT COUNT(*) from mydb.mytable
menghitung hanya bacaan berulang atau menyertakan bacaan yang telah dilakukan dan yang tidak berkomitmen.Anda dapat mencoba menstabilkan hal-hal sedikit dengan mengaktifkan innodb_stats_on_metadata .
Menurut Dokumentasi MySQL di innodb_stats_on_meta_data
Menonaktifkannya mungkin atau mungkin tidak memberi Anda hitungan yang lebih stabil dalam hal menyiapkan paket EXPLAIN. Ini dapat memengaruhi kinerja
SELECT COUNT(*) from mydb.mytable
baik cara yang baik, cara yang buruk, atau tidak sama sekali. Cobalah dan Lihat !!!sumber
Untuk pemula tidak ada yang namanya 'hitungan saat ini' untuk menyimpan dalam variabel. Permintaan seperti
SELECT COUNT(*) FROM ...
tunduk pada tingkat isolasi saat ini dan semua transaksi yang tertunda bersamaan. Bergantung pada tingkat isolasi, kueri dapat melihat atau tidak melihat baris dimasukkan atau dihapus dengan menunggu transaksi yang tidak dikomit. Satu-satunya cara untuk menjawab adalah dengan menghitung baris yang terlihat oleh transaksi saat ini.Perhatikan bahwa saya bahkan tidak menyentuh subjek yang lebih sulit dari transaksi bersamaan yang dimulai atau berakhir selama penghitungan. Belum lagi kembalikan ...
sumber
COUNT(*)
kueri sebelumnya jarang diperlukan dalam kenyataan & biasanya hasil dari pengalaman pengembang (hitung baris sebelum kita memilihnya!) Atau desain aplikasi yang buruk.SELECT COUNT(*)
, tambahkan non-dioptimalkanWHERE
ke tabel dan Anda akan memiliki beberapa pengguna yang membawa db berlutut untuk beberapa penghitung stat yang bermanfaat.Meskipun secara teori dimungkinkan untuk menjaga penghitungan jumlah baris yang akurat untuk tabel tertentu dengan InnoDB, itu akan mengorbankan banyak penguncian, yang akan berdampak negatif pada kinerja. Itu juga akan berbeda berdasarkan tingkat isolasi.
MyISAM sudah melakukan penguncian tingkat tabel, jadi tidak ada biaya tambahan di sana.
Saya jarang memerlukan jumlah baris untuk sebuah tabel, meskipun saya menggunakan COUNT (*) sedikit. Saya biasanya memiliki klausa WHERE terlampir. Menggunakan indeks yang efisien pada set hasil yang kecil, saya menemukan bahwa mereka cukup cepat.
Saya tidak setuju bahwa penghitungan tidak akurat. Hitungannya mewakili snapshot data, dan saya selalu menganggapnya tepat.
Singkatnya, MySQL menyerahkan kepada Anda untuk mengimplementasikan ini untuk InnoDB. Anda bisa menyimpan hitungan dan menambah / mengurangi setelah setiap kueri. Padahal, solusi yang lebih mudah mungkin untuk beralih ke MyISAM.
sumber