Đoạn mã nào sẽ chạy nhanh hơn?

for ($i = 0; $i < count($keyword) ; $i++) { 
$arr = mysqli_query("select * from pictures as a inner join pictures_tags as b on (a.id = b.pic_id) inner join tags as c on (b.tag_id = c.id) where c.tag = '$keyword[$i]' LIMIT 1",$conn);

if (!$arr) {

	array_push($n,$keyword[$i]);

}else{

	array_push($y,$keyword[$i]);
}
}

So với nếu select tất cả ra rồi dùng in_array() thì cái nào nhanh hơn ạ ?
Em xin cảm ơn!

Bạn implode keyword rồi dùng IN xem

Với mấy món này (lại còn là php nữa), thì bạn nên tự benchmark bằng cách đo thời gian.

1 Like

Select tất cả vào array rồi dùng in_array chắc chắn sẽ nhanh hơn. Lý do là với đoạn mã ở trên, bạn phải chạy một query cho mỗi keyword. Việc kết nối vào CSDL và thực hiện query sẽ chậm hơn so với việc kiểm tra trong memory rất nhiều (khi dùng in_array). Do đó, chúng ta có thể làm một phép so sánh nhu sau:

  • Nếu bạn dùng đoạn mã mà bạn cung cấp thì bạn sẽ thực hiện n query (với n là chiều dài của array keyword) và n lần push cho các keyword
  • Nếu bạn dùng in_array thì bạn chỉ chạy một query và một vòng lặp để kiểm tra với in query và push cho các keyword. Vòng lặp này cũng có độ dài n, tuy nhiên, vì nó thực hiện trong memory nên nó sẽ nhanh hơn n lần query rất nhiều.

Từ phân tích trên, bạn có thể thấy cái nào nhanh hơn rồi.

Còn nếu bạn muốn tối ưu thì bạn có thể sửa câu lệnh query của bạn đại khái như sau:

$arr = mysqli_query(“select c.tag from pictures as a inner join pictures_tags as b on (a.id = b.pic_id) inner join tags as c on (b.tag_id = c.id) where c.tag = ‘$keyword[$i]’ LIMIT 1”,$conn);

và dùng các hàm thích hợp để tìm phần giao giữa $arr và $keyword và push vào $n, phần còn lại thì push vào $y. Trong cách này, bạn hoàn toàn không dùng đến vòng lặp nên việc thực thi sẽ nhanh hơn nữa.

Tôi không chuyên về PHP nên không có câu trả lời chính xác về các hàm phải dùng. Nhưng nếu bạn muốn tối ưu thời gian thực thi thì bạn có thể tìm hiểu theo hướng đó.

Một vấn đề nữa là khi bạn dùng SQL, nên tránh dùng SELECT * vì nó cũng sẽ ảnh hưởng tới thời gian chạy nếu cơ sở dữ liệu quá lớn. Do đó, câu query ban đầu của bạn có thể được sửa lại như sau:

$arr = mysqli_query(“select 1 from pictures as a inner join pictures_tags as b on (a.id = b.pic_id) inner join tags as c on (b.tag_id = c.id) where c.tag = ‘$keyword[$i]’ LIMIT 1”,$conn);

Lý do của SELECT 1 ở đây là bởi vì bạn không quan tâm đến kết quả nào được trả về trong query, bạn chỉ quan tâm đến là nó có kết quả hay không thôi (theo logic của đoạn mã bạn dùng, bạn chỉ dùng $arr để kiểm tra điều kiện có kết quả hay không chứ không dùng đến giá trị thực sự của nó).

3 Likes

ví dụ tags của em trả về 1 mảng gồm hơn 100 nghìn tag . Thì cách cho vào array vẫn nhanh hơn phải ko anh ?

Chắc chắn sẽ nhanh hơn. Tuy nhiên nếu kết quả trả về hơn 100 nghìn tags thì lúc đó bạn sẽ đối diện với một vấn đề khác: bộ nhớ. Bộ nhớ server của bạn có thể đủ lớn để chứa 100 nghìn kết quả trong một session. Tuy nhiên nếu bạn có nhiều session đồng thời (ví dụ như có nhiều người cùng truy cập Web site của bạn cùng lúc) thì điều này có thể rất tệ. Do đó, nếu kết quả lớn như vậy thì bạn có thể phải xem xét chia nhỏ mảng $keyword ban đầu ra và query theo các mảng con. Dĩ nhiên khi làm như vậy thì bạn phải thực hiện nhiều hơn một query, nhưng vẫn là tốt hơn n query.

Không có một câu trả lời đúng cho mọi trường hợp. Bạn phải giải quyết tùy theo hoàn cảnh thôi.

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?