Cách tăng tốc độ chạy 1 script PHP + MySQL

em có 1 đoạn code như này

<?php
	include '../connect.php';
	$layvip = mysqli_query($conn, 'SELECT `user_id`, `max_like`, `end`, `likes` FROM vip ORDER BY RAND() LIMIT 10');
	while($vip = mysqli_fetch_assoc($layvip)){
		if($vip['end'] > time()){
			$feed = json_decode(file_get_contents('https://graph.facebook.com/'.$vip['user_id'].'/feed?limit=1&fields=id,likes&method=get&access_token='.$tokenx),true);
			$uid = explode('_', $feed['data'][0]['id'])[0];
        	if(($uid == $vip['user_id']) && ($feed['data'][0]['likes']['count'] < $vip['max_like'])){
				$laytoken = mysqli_query($conn, "SELECT access_token FROM autolike ORDER BY RAND() LIMIT {$vip['likes']}");
				while($token = mysqli_fetch_assoc($laytoken)){
					file_get_contents('https://graph.fb.me/'.$feed['data'][0]['id'].'/likes?access_token='.$token['access_token'].'&method=post');
				}
			}
		}
	}
?>

file này để cron job liên tục chạy like cho các ID Facebook trong cơ sở dữ liệu, nhưng em có 400 recoreds trong bảng vip ( script trên rand id và chọn ra 10 id 1 lần chạy) nhưng khi chạy rất chậm ko lên like nhanh được, e đã Index cho các column cần truy vấn nhiều nhưng vẫn chậm quá, vậy có cách nào tối ưu hơ ko ạ ? $tokenx là 1 mã token trong file connect.php nhé !!!
e cảm ơn!!

1 Like

Mình không cần biết bạn tối ưu hay tổ chức sql tồi hay tốt đến mức nào nhưng có 1 điểm nghẽn cổ chai chính là phần connect với FB, cứ cho 1 request mất 0.5 s thì với 400 record đã mất 200s rồi, chi mà không chậm

2 Likes

có thể dùng nodejs + mysql thay cho php+mysql đc ko nhỉ ?

tùy bạn thôi, nhưng bạn đã thử đo xem nút cổ chai là ở đâu chưa, cứ hùng hục vào tối ưu không phải là cách, vừa mất thời gian mà lại không được gì. Có thể nghĩ sang cách sử dụng đa luồng cũng là 1 cách tăng tốc đối với những job không có liên quan đến nhau

php đa luồng ntn bạn ?

https://secure.php.net/pthreads

Đơn giản là nhét 400 vòng lặp vào 400 hàm/Generator/Anonymous Function, sau đó dùng thread call 400 hàm đó bằng foreach.
Cách dùng luồng này thực sự không ổn vì bạn sẽ gọi khoảng [~400 thread?](tùy vào cấu trúc hệ điều hành/phần cứng).
Nên tìm một thư viện async để chạy. Async nó không hẳn là thread nên có thể thoải mái sử dụng.

3 Likes

hoặc nếu k muốn dùng thư viện ngoài thì chia chunk 400 record ra thành 5-6 phần, cho mỗi phần đó vào 1 thread cũng là 1 cách giảm áp lực cho hệ thống. Còn nếu có kiến thức sâu thì hoàn toàn có thể làm 1 bộ lib async nho nhỏ dựa trên thread

2 Likes
  1. Về mặt thuật toán: OK
  2. Về mặt tốc độ: bác đang chạy để truy xuất đến API của FB, thông tin đi và về cũng cần thời gian chứ không phải ngay local mà chạy một phát là xong.

Bản chất php là tuần tự, nếu gởi tính hiệu đi nó sẽ đợi tính hiệu về rồi làm tiếp, không khác được. Khí đó bác phải đợi.
Muốn tăng tốc trong trường hợp này bác nên đổi sang Nodejs hoặc chia data trong table [vip] thành nhiều khoản và cho nhiều file/thread chạy song song.

1 Like

chắc em tìm hiểu cài nodejs lên vps em đang dùng là Linux, centos 6 xong là viết file như kia nhưng = nodejs ( .js ) phải không mấy anh ??

Cái này chậm là do gọi nhiều request đến facebook chứ không liên quan MySQL cho lắm.

Có vài cách giải quyết thế này, bạn thử xem sao, mình chưa thử :smile:

p/s: NodeJs có tác dụng gì trong trường hợp này nhỉ?

3 Likes

1 đoạn crawling lên GraphQL server đã thấy bất thường rồi.

<?php
file_get_contents('https://graph.fb.me/'.$feed['data'][0]['id'].'/likes?access_token='.$token['access_token'].'&method=post');
1 Like

Có thể hy sinh bộ nhớ RAM bằng cách Load tất cả dữ liệu của bẳng truy vấn vào 1 biến (cần config php.ini nếu tràn bộ nhớ).

Truy vấn SQL không nên dùng RAND() vì CSDL sẽ order rồi shuffle dữ liệu nên hiệu năng giảm. Thay vào đó bạn có thể load vào 1 biến array rồi dùng $arr[rand(min, max)]

2 Likes

em đã chuyern sang nodejs và test thành cong trên local, giờ em muốn up len vps và cron chạy tự động thì làm ntn ạ, Cách cron 1 file nodejs trên vps giúp em với ạ!!

Dùng cái này: https://github.com/kelektiv/node-cron

đã ok chưa :v haha 2 năm r nhỉ

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