2013-03-14 37 views
5

Bảng nằm trong bảng InnoDB. Dưới đây là một số thông tin có thể hữu ích.Truy vấn MySQL rất chậm. Đếm (*) trên cột được lập chỉ mục

EXPLAIN SELECT COUNT(*) AS y0_ FROM db.table this_ WHERE this_.id IS NOT NULL; 

+----+-------------+-------+-------+---------------+---------+---------+------+---------+--------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra     | 
+----+-------------+-------+-------+---------------+---------+---------+------+---------+--------------------------+ 
| 1 | SIMPLE  | this_ | index | PRIMARY  | PRIMARY | 8  | NULL | 4711235 | Using where; Using index | 
+----+-------------+-------+-------+---------------+---------+---------+------+---------+--------------------------+ 
1 row in set (0.00 sec) 

mysql> DESCRIBE db.table; 
+--------------+--------------+------+-----+---------+-------+ 
| Field  | Type   | Null | Key | Default | Extra | 
+--------------+--------------+------+-----+---------+-------+ 
| id   | bigint(20) | NO | PRI | NULL |  | 
| id2   | varchar(28) | YES |  | NULL |  | 
| photo  | longblob  | YES |  | NULL |  | 
| source  | varchar(10) | YES |  | NULL |  | 
| file_name | varchar(120) | YES |  | NULL |  | 
| file_type | char(1)  | YES |  | NULL |  | 
| created_date | datetime  | YES |  | NULL |  | 
| updated_date | datetime  | YES |  | NULL |  | 
| createdby | varchar(50) | YES |  | NULL |  | 
| updatedby | varchar(50) | YES |  | NULL |  | 
+--------------+--------------+------+-----+---------+-------+ 
10 rows in set (0.05 sec) 

Truy vấn giải thích cho tôi kết quả ngay tại đó. Nhưng truy vấn thực tế đã chạy khá lâu. Làm thế nào tôi có thể sửa lỗi này? Tôi đang làm gì sai?

Tôi về cơ bản cần tìm ra số lượng photos có trong bảng này. Ban đầu, coder gốc có một truy vấn kiểm tra WHERE photo IS NOT NULL (mất 3 giờ +) nhưng tôi đã thay đổi truy vấn này để kiểm tra cột id vì nó là khóa chính. Tôi mong đợi một hiệu suất rất lớn đạt được ở đó và đã mong đợi một câu trả lời trong một giây nhưng điều đó dường như không phải là trường hợp.

Tôi cần phải làm gì để tối ưu hóa loại cơ sở dữ liệu nào? Tôi nghĩ rằng truy vấn là tốt nhưng cảm thấy tự do để sửa tôi nếu tôi sai.

Edit: mysql Ver 14,14 distrib 5.1.52, cho redhat-linux-gnu (x86_64) sử dụng readline 5.1

Tái bút: Tôi đổi tên các bảng đối với một số lý do điên. Tôi không thực sự có cơ sở dữ liệu có tên db và bảng được đặt tên là table.

+0

Làm thế nào để 'SELECT COUNT (*) FROM db.table' hoạt động? (Vì 'id' là không null, nó tương đương với truy vấn hiện tại của bạn.) – ruakh

+0

Xấu. Mất hơn 10 phút (Tôi không thể nói cho bạn chắc chắn nhưng đó là bao lâu tôi đã chờ đợi). – Sanchit

Trả lời

9

Thời lượng 'dài' là bao lâu? Có bao nhiêu hàng trong bảng này?

Bảng MyISAM theo dõi số lượng hàng có, vì vậy COUNT (*) đơn giản sẽ luôn trả về gần như ngay lập tức. InnoDB, mặt khác hoạt động khác nhau: một bảng InnoDB không theo dõi có bao nhiêu hàng nó có, và vì vậy khi bạn COUNT (*), nó theo nghĩa đen phải đi và đếm từng hàng. Nếu bạn có một bảng lớn, điều này có thể mất một vài giây.

EDIT: Thử COUNT(ID) thay vì COUNT(*), trong đó ID là cột được lập chỉ mục không có NULL trong đó. Điều đó có thể chạy nhanh hơn.

EDIT2: Nếu bạn đang lưu trữ dữ liệu nhị phân của các tệp trong longblob, bảng của bạn sẽ lớn, điều này sẽ làm chậm mọi thứ.

giải pháp có thể:

  1. Sử dụng MyISAM thay vì InnoDB.
  2. Duy trì số lượng của riêng bạn, có thể sử dụng trình kích hoạt khi chèn và xóa.
  3. Loại bỏ dữ liệu nhị phân thành một bảng khác hoặc tốt hơn là các tệp thông thường.
+0

InnoDB mất bao lâu trên bảng hàng 4.7million? Câu giải thích cho tôi câu trả lời của tôi trong một giây! – Sanchit

+0

Đúng, đó thực sự chỉ là ước tính! http://dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html – aidan

+0

Tôi không chắc chắn một truy vấn đếm trên hàng 4,7m sẽ mất bao lâu, bởi vì nó sẽ phụ thuộc vào những thứ khác như CPU tốc độ, tải CPU, vv, nhưng có thể 5 giây? – aidan

Các vấn đề liên quan