2010-03-20 34 views
28

Tôi chỉ tự hỏi phương pháp nào hiệu quả nhất nếu tôi chỉ muốn lấy số hàng trong bảng.SQL & PHP - Đó là mysql_num_rows() hoặc 'select count()' nhanh hơn?

$res = mysql_query("SELECT count(*) as `number` FROM `table1`"); 
$count = mysql_fetch_result($res,0,'number'); 

hoặc

$res = mysql_query("SELECT `ID` FROM `table1`"); 
$count = mysql_num_rows($res); 

Bất cứ ai thực hiện bất kỳ thử nghiệm đàng hoàng về vấn đề này?

Trả lời

30

mysql_query() chuyển tất cả các bản ghi kết quả từ MySQL vào máy tính php trước khi nó trả về (không giống như mysql_unbufferd_query()). Điều đó một mình sẽ làm cho phiên bản mysql_num_rows() chậm hơn.

Hơn nữa đối với một số công cụ (như MyISAM), MySQL có thể đáp ứng yêu cầu Đếm (*) từ chỉ mục của bảng without hitting the actual data. Mặt khác, SELECT * FROM foo cho kết quả quét toàn bộ bảng và MySQL phải đọc từng tập dữ liệu.

+0

Cảm ơn mọi người đã gửi bài đăng của bạn, phải chọn một bài đăng. Câu trả lời của VolkerK là dứt khoát và mang tính thông tin. Cảm ơn :) – Joel

0

Tôi đoán count(1) sẽ còn nhanh hơn:

$res = mysql_query("SELECT count(1) as `number` FROM `table1`"); 
$count = mysql_fetch_result($res,0,'number'); 

Mặc dù chưa thử các phương pháp đề xuất, là người đầu tiên làm cho cơ sở dữ liệu lấy tất cả các hồ sơ và đếm chúng trong cơ sở dữ liệu, thứ hai làm cho cơ sở dữ liệu lấy một riêng biệt cho tất cả các bản ghi và đếm số lượng kết quả trên máy chủ. Theo quy tắc, bạn càng lấy ít dữ liệu hơn cho một bản ghi cụ thể thì sẽ mất ít thời gian hơn vì vậy tôi sẽ bỏ phiếu cho phương thức đầu tiên được cập nhật (tìm nạp hằng số cho mỗi bản ghi và đếm số lượng các hằng số được tìm nạp).

+1

Nếu công cụ lưu trữ là MyISAM và có e không có điều kiện 'WHERE',' count (*) 'sẽ nhanh hơn, vì số lượng bản ghi chính xác được lưu trữ cho các bảng MyISAM. –

+1

Dự đoán của bạn có thể ngược lại - COUNT (*) là cách thành ngữ để nhận kích thước của tập kết quả và bất kỳ cơ sở dữ liệu nào có giá trị muối của nó sẽ được tối ưu hóa cho nó. –

+2

Và * trong 'Đếm (*)' có nghĩa là "Đừng nhìn vào dữ liệu, chỉ cần đếm các bản ghi" như trái ngược với Đếm (tên). – VolkerK

0

Tôi thực sự không nghĩ rằng bất kỳ thử nghiệm nào là cần thiết.

Làm COUNT trong truy vấn SQL

1) Gửi chỉ có một hàng dữ liệu sao lưu các cho khách hàng (thay vì mỗi hàng)

2) Cho phép SQL làm count cho bạn đó là có khả năng sẽ luôn đi để nhanh hơn PHP.

6

Chắc chắn là người đầu tiên. MySQL thường có thể làm điều này bằng cách xem chỉ mục chứ không phải toàn bộ bảng và nếu bạn sử dụng MyISAM (mặc định), số hàng cho bảng được lưu trữ trong siêu dữ liệu của bảng và sẽ được trả lại ngay lập tức.

Phương pháp thứ hai của bạn sẽ không chỉ đọc toàn bộ bảng vào bộ nhớ mà còn gửi cho khách hàng thông qua mạng trước khi khách hàng đếm các hàng. Vô cùng lãng phí!

-3

Sử dụng Đếm có chỉ mục và inodb khiến quá chậm, nhưng khi sử dụng nó với mysqli_num_rows, nó sẽ trả về mà không bị chậm trễ. bạn có thể kiểm tra kết quả mysqli_num_rows tại http://ssajalandhar.org/generalinstruction-0-1-0.html nó sẽ không mất một phần nhỏ giây để tải. Đối với tôi mysqli hoạt động tuyệt vời.

6

Kiểm tra trong cơ sở dữ liệu với hơn sau đó 2300000 hàng, gõ: InnoDB, kích thước gần 1 GiB, sử dụng xhprof

test1:

....SELECT COUNT(id) as cnt FROM $table_name....; 
     row= mysqli_fetch_assoc($res2); 
    echo $row['cnt']; 
     //result1: 
     1,144,106 
     1,230,576 
     1,173,449 
     1,163,163 
     1,218,992 

test2:

....SELECT COUNT(*) as cnt FROM $table_name....; 
     row= mysqli_fetch_assoc($res2); 
    echo $row['cnt']; 
//result2: 
1,120,253 
1,118,243 
1,118,852 
1,092,419 
1,081,316 

Test3:

....SELECT * FROM $table_name....; 
    echo mysqli_num_rows($res2); 
    //result3: 
7,212,476 
6,530,615 
7,014,546 
7,169,629 
7,295,878 

test4:

 ....SELECT * FROM $table_name....; 
     echo mysqli_num_rows($res2); 
     //result4: 
1,441,228 
1,671,616 
1,483,050 
1,446,315 
1,647,019 

kết luận: Phương pháp nhanh nhất là trong test2:

....SELECT COUNT(*) as cnt FROM $table_name....; 
     row= mysqli_fetch_assoc($res2); 
    echo $row['cnt']; 
Các vấn đề liên quan