mysql mất quá nhiều thời gian để gửi dữ liệu


9

Tôi có một bảng đơn giản với hàng triệu bản ghi (14.000.000) và đối với một truy vấn đơn giản, đó là dành quá nhiều thời gian để "gửi dữ liệu".

Cái bàn

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;

Truy vấn đơn giản

mysql> SELECT * FROM details WHERE id = 3014595;

Giải thích

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 |       |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+

Hồ sơ cho truy vấn

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 |
+--------------------------------+----------+

Như bạn có thể thấy, SELECTcâu lệnh đã sử dụng chỉ mục và chỉ đọc 1482 hàng. Tuy nhiên, truy vấn đã dành 7.536960 giây để gửi dữ liệu. Nó giống như truy vấn đọc nhiều hàng hơn nó cần.

Đó là một truy vấn đơn giản, chỉ với 7 trường (hàng avg 59 Byte) và không có chức năng ưa thích. Bất kỳ ý tưởng những gì có thể gây ra điều này?

Lưu ý: id là ID người dùng. Mỗi người dùng có thể có ít nhất một mục nhập cho mỗi giờ mỗi ngày. Do đó, id không phải là duy nhất.

Chỉnh sửa: Tôi có một bảng khác có cùng cấu trúc và nhiều hàng hơn (34 Triệu). Nếu tôi chạy cùng một truy vấn trên bảng lớn hơn này, nó sẽ trả về kết quả sau chưa đầy 1 giây.

Sự khác biệt duy nhất là bảng lớn hơn không nhận được nhiều truy vấn như bảng nhỏ hơn.

  • Có thể là số lượng truy vấn đang làm chậm quá trình? Bộ nhớ cache MySQL được bật. Tôi cũng đã CakePHP lưu trữ các truy vấn để giảm số lượng truy vấn.
  • Có thể là tập tin nơi bảng được lưu bị hỏng hoặc một cái gì đó?

Cập nhật Vấn đề đã được giải quyết bằng cách tách tầng dữ liệu khỏi tầng web. Tầng dữ liệu cũng được nâng cấp trên RAM và đang chạy trên raid10.


Có bao nhiêu hàng SELECTtrả về?
hjpotter92

1591 rows in set (16.48 sec)Tôi chạy lại truy vấn, đây là lý do tại sao thời lượng là khác nhau. Phải mất 16 giây (!!)
rlcabral

thay vì sử dụng * hãy thử sử dụng các cột và sau đó xem sự khác biệt của nó
Muhammad Raheel

Không. Cùng một kết quả.
rlcabral

Cố gắng làm cho cột ID trở thành một chỉ mục chính đơn giản. Vì ID phải là một trường duy nhất, bạn không cần tạo các chỉ mục phức tạp với nó. Điều này sẽ làm cho tìm kiếm của bạn bằng khóa chính nhanh như đèn chớp.
Alexander Pravdin

Câu trả lời:


1

Đối với bất kỳ ai vấp phải câu hỏi này và tự hỏi, ngay cả khi không nâng cấp RAM, tại sao việc gửi dữ liệu lại mất nhiều thời gian hơn. Đó là bởi vì việc gửi dữ liệu thực sự bao gồm thời gian tìm kiếm dữ liệu sẽ được gửi.

https://dev.mysql.com/doc/refman/5.7/vi/general-thread-states.html

Chuỗi này đang đọc và xử lý các hàng cho một câu lệnh CHỌN và gửi dữ liệu đến máy khách. Vì các hoạt động xảy ra trong trạng thái này có xu hướng thực hiện một lượng lớn truy cập đĩa (đọc), nên nó thường là trạng thái chạy lâu nhất trong suốt vòng đời của một truy vấn nhất định.


-2

Hãy thử Tối ưu hóa bảng bằng cách tối ưu hóa tablename của bảng và kiểm tra trạng thái.

Những thay đổi lớn cần được thực hiện:

Alter table tablename engine = 'INNODB'

Điều này sẽ giúp bạn rất nhiều và có thể nên có một khóa chính trong bảng nhưng bạn đã thêm ba cột làm khóa chính.


-3

Tạo chỉ mục riêng cho id:

thay đổi chi tiết bảng thêm khóa d1 (id);

Để chỉ số này có hiệu lực, hãy khởi động lại MySQL hoặc

phân tích chi tiết bảng;

Nếu có thể, bạn cũng có thể thay đổi cơ sở dữ liệu thành InnoDB để được hỗ trợ giao dịch và các lợi ích khác.


Điều này sẽ giúp như thế nào?
Colin 't Hart
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.