Mengapa menghitung (*) lambat, ketika menjelaskan tahu jawabannya?


14

Kueri ini: select count(*) from planner_eventmembutuhkan waktu yang sangat lama untuk dijalankan - begitu lama, saya menyerah dan membunuhnya sebelum selesai. Namun, ketika saya menjalankan explain select count(*) from planner_event, saya bisa melihat kolom di output dengan jumlah baris (14m).

Bagaimana menjelaskan bisa mendapatkan jumlah baris secara instan, tetapi menghitung (*) membutuhkan waktu lama untuk dijalankan?


COUNT (*) tanpa sebab WHERE akan menyebabkan pemindaian tabel pada mesin InnoDB .. MyISAM dapat mengirimkan hitungan secara langsung karena COUNT tidak ada dalam file header dari tabel.
Raymond Nijland

Jawaban:


16

Jelaskan menggunakan statistik yang dikumpulkan sebelumnya (digunakan oleh pengoptimal kueri). Melakukan select count(*)pembacaan SETIAP blok data.

Berikut cara murah untuk mendapatkan taksiran jumlah baris:

select TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME='planner_event';

Bahkan jika Anda melakukannya select count(id), mungkin masih membutuhkan waktu yang sangat lama, kecuali Anda memiliki indeks sekunder aktif id(juga dengan asumsi idadalah KUNCI UTAMA). Karena semua data (termasuk Data Baris) disimpan dalam indeks B-Tree, melakukan a select count(PK_COLUMN)masih banyak IO (perlu membaca semua halaman data). Jika Anda memiliki indeks sekunder di bidang PK, itu akan dapat melakukan lebih sedikit IO untuk melakukan penghitungan.


I_S.TABLES memberi Anda perkiraan yang sama dengan yang EXPLAINmemberi Anda.
Rick James

Permintaan tidak ada AND TABLE_SCHEMA='my_database', jika tidak Anda akan mendapatkan beberapa hasil kembali jika Anda memiliki tabel dengan nama yang sama di database lain.
cz

3

Jelaskan mendapat nomor dari beberapa "statistik" yang digunakan untuk memperkirakan hal-hal untuk Pengoptimal. Angka itu bisa jauh dari benar - saya kadang-kadang melihatnya lebih dari faktor 2 (lebih tinggi atau lebih rendah) daripada nilai yang tepat.

Melakukan COUNT(*)pada tabel InnoDB harus memindai tabel untuk menghindari salah perhitungan catatan yang sibuk dimasukkan / dihapus oleh koneksi lain tetapi belum "dilakukan". Sebenarnya, cukup baik untuk melakukan pemindaian penuh pada beberapa indeks, belum tentu seluruh tabel (yang berisi PRIMARY KEY).

Berapa banyak RAM yang Anda miliki? Apa nilainya innodb_buffer_pool_size? Mungkin membantu jika itu sekitar 70% dari RAM.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.