Saya memiliki tabel sederhana dengan jutaan catatan (14.000.000) dan untuk permintaan sederhana itu menghabiskan terlalu banyak waktu "mengirim data".
Meja
CREATE TABLE IF NOT EXISTS details (
id int(11) NOT NULL,
date date NOT NULL,
time int(2) NOT NULL,
minutes_online decimal(5,0) NOT NULL,
minutes_playing decimal(5,0) NOT NULL,
minutes_chatting decimal(5,0) NOT NULL,
minutes_away decimal(5,0) NOT NULL
PRIMARY KEY (id,date,time)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
Pertanyaan sederhana
mysql> SELECT * FROM details WHERE id = 3014595;
Menjelaskan
mysql> EXPLAIN SELECT * FROM details WHERE id = 3014595;
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | details | ref | PRIMARY | PRIMARY | 4 | const | 1482 | |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
Profil untuk kueri
mysql> SHOW PROFILE FOR QUERY 1;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000024 |
| checking query cache for query | 0.000078 |
| checking permissions | 0.000014 |
| Opening tables | 0.000126 |
| System lock | 0.000011 |
| Table lock | 0.000030 |
| init | 0.000027 |
| optimizing | 0.000117 |
| statistics | 0.040077 |
| preparing | 0.000029 |
| executing | 0.000006 |
| Sending data | 7.536960 |
| end | 0.000013 |
| query end | 0.000004 |
| freeing items | 0.000037 |
| storing result in query cache | 0.000006 |
| logging slow query | 0.000003 |
| cleaning up | 0.000006 |
+--------------------------------+----------+
Seperti yang Anda lihat, SELECT
pernyataan itu menggunakan indeks dan hanya membaca 1482 baris. Namun, kueri menghabiskan 7,536960 detik mengirimkan data. Ini seperti permintaan membaca lebih banyak baris yang dibutuhkan.
Ini adalah kueri sederhana, dengan hanya 7 bidang (baris rata-rata 59 Bytes) dan tidak ada fungsi mewah. Adakah yang tahu apa yang menyebabkan ini?
Catatan: id adalah ID pengguna. Setiap pengguna mungkin memiliki setidaknya satu entri untuk setiap jam setiap hari. Karenanya, id tidak unik.
Sunting: Saya punya meja lain dengan struktur yang sama dan lebih banyak baris (34 Juta). Jika saya menjalankan kueri yang sama pada tabel yang lebih besar ini, ia mengembalikan hasilnya dalam waktu kurang dari 1 detik.
Satu-satunya perbedaan adalah bahwa tabel yang lebih besar tidak mendapatkan kueri sebanyak tabel yang lebih kecil.
- Apakah mungkin bahwa jumlah kueri memperlambat proses? Cache MySQL menyala. Saya juga telah men-cache CakePHP kueri untuk mengurangi jumlah kueri.
- Apakah mungkin file tempat tabel disimpan rusak atau apa?
Pembaruan Masalah ini dipecahkan dengan memisahkan tingkat data dari tingkat web. Tingkat data juga mendapat peningkatan pada RAM dan berjalan pada raid10.
sumber
SELECT
dikembalikan?1591 rows in set (16.48 sec)
Saya menjalankan kueri lagi, inilah mengapa durasinya berbeda. Sekarang butuh 16 detik (!!)Jawaban:
Bagi siapa pun yang tersandung pada pertanyaan ini dan bertanya-tanya, bahkan tanpa upgrade RAM, mengapa mengirim data membutuhkan waktu lebih lama. Itu karena mengirim data sebenarnya termasuk waktu mencari data yang akan dikirim.
https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html
sumber
Coba Optimalkan tabel menggunakan nama tabel Optimize table dan periksa statusnya.
Perubahan besar perlu dilakukan:
Ini akan banyak membantu Anda dan mungkin harus ada satu kunci utama dalam tabel tetapi Anda telah menambahkan tiga kolom sebagai kunci utama.
sumber
Buat indeks terpisah untuk id:
Untuk menerapkan indeks ini, mulai ulang MySQL atau
Jika memungkinkan, Anda juga dapat mengubah database ke InnoDB untuk dukungan transaksi dan manfaat lainnya.
sumber