mysql terlalu lama untuk mengirim data


9

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, SELECTpernyataan 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.


Berapa banyak baris yang SELECTdikembalikan?
hjpotter92

1591 rows in set (16.48 sec)Saya menjalankan kueri lagi, inilah mengapa durasinya berbeda. Sekarang butuh 16 detik (!!)
rlcabral

alih-alih menggunakan * cobalah menggunakan kolom dan kemudian lihat perbedaannya
Muhammad Raheel

Nggak. Hasil yang sama
rlcabral

Cobalah untuk membuat kolom ID indeks utama sederhana. Karena ID harus berupa bidang unik, Anda tidak perlu membuat indeks yang rumit dengannya. Ini akan membuat pencarian Anda dengan kunci utama menjadi cepat seperti kecepatan lampu.
Alexander Pravdin

Jawaban:


1

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

Utas membaca dan memproses baris untuk pernyataan SELECT, dan mengirim data ke klien. Karena operasi yang terjadi selama keadaan ini cenderung melakukan sejumlah besar akses disk (baca), sering kali keadaan terpanjang berjalan selama masa permintaan yang diberikan.


-2

Coba Optimalkan tabel menggunakan nama tabel Optimize table dan periksa statusnya.

Perubahan besar perlu dilakukan:

Alter table tablename engine = 'INNODB'

Ini akan banyak membantu Anda dan mungkin harus ada satu kunci utama dalam tabel tetapi Anda telah menambahkan tiga kolom sebagai kunci utama.


-3

Buat indeks terpisah untuk id:

ubah detail tabel tambahkan kunci d1 (id);

Untuk menerapkan indeks ini, mulai ulang MySQL atau

menganalisis detail tabel;

Jika memungkinkan, Anda juga dapat mengubah database ke InnoDB untuk dukungan transaksi dan manfaat lainnya.


Bagaimana ini membantu?
Colin 't Hart
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.