Tôi không phải là một coder php tuyệt vời (tôi đến từ C++). Tôi đang sử dụng php chỉ cho mục nhập cơ sở dữ liệu.PhP, MySql - Tối ưu hóa Mã số
Tôi có một cơ sở dữ liệu như sau:
UserId (an unique int)
AsyncPointsAverage (float)
AsyncPointsAverageRank (a position based on the value immediately above)
AsyncPointsRecentAverage (float an average for the last 5 tests only)
AsyncPointsRecentAverageRank (a position based on the value immediately above)
Có khoảng 1.000-1.500 mục trong bảng đó. Mỗi buổi sáng và buổi chiều, 5 người đều làm bài kiểm tra có ảnh hưởng trung bình tổng thể và trung bình gần đây của họ. (Điều này được cập nhật ở nơi khác, nhưng không được hiển thị ở đây.) Sau đó được tính cho 5 người đó, sau đó thứ hạng của tất cả 1000-1500 sẽ được thực hiện, vì vậy tôi đã viết mã bên dưới. Nó có tối ưu không?
Điều tôi quan tâm nhất là tôi đang thực hiện cập nhật MySql khoảng 1000 lần. Điều đó có tuyệt không? Tôi có nên làm theo cách khác không? (Cũng cảm thấy tự do để tối ưu hóa các mã khác trong hàm. Như tôi đã nói, tôi từ một C++ nền, do đó, không thực sự biết các sắc thái của php.)
// Sorts by array entry 1
function ReRankCompareAverage($a, $b)
{
if($a[1] == $b[1]) return 0;
else return ($a[1] > $b[1] ? 1 : -1);
}
// Sorts by array entry 2
function ReRankCompareAverageRecent($a, $b)
{
if($a[2] == $b[2]) return 0;
else return ($a[2] > $b[2] ? 1 : -1);
}
function ReRank($db)
{
$i = 0, $j = 0;
$usersARR = null;
$stmt = $db->prepare("SELECT UserId, AsyncPointsAverage, AsyncPointsRecentAverage FROM studenttable");
$stmt->execute();
if($stmt && isset($stmt) && $stmt->rowCount() > 0)
{
$i = 0;
while(($row = $stmt->fetch(PDO::FETCH_ASSOC)))
{
$usersARR[$i][0] = intval($row['UserId']);
$usersARR[$i][1] = floatval($row['AsyncPointsAverage']);
$usersARR[$i][2] = floatval($row['AsyncPointsRecentAverage']);
$i++;
}
}
$stmt->closeCursor(); // mysql_free_result equivalent
// The first pass of $j == 3 does the ranking by Average, filling position $usersARR[][3] with that rank
// The second pass of $j == 4 does the ranking by AverageRecent, filling position $usersARR[][4] with that rank
for($j = 3, $j <= 4; $j++)
{
$iCompare = $j == 3 ? 1 : 2;
usort($usersARR, $j == 3 ? "ReRankCompareAverage" : "ReRankCompareAverageLast");
$count = count($usersARR);
if($count > 0)
{
// Start it off, with the person with the highest average is rank 1
$usersARR[$count - 1][$j] = 1; // Position $j is filled with the rank
// Now loop starting from the second one down
for($i = $count - 2, $rank = 1; $i >= 0; $i--)
{
// Only change the rank if the next one down is strictly lower than the one above, otherwise will share the same rank
if($usersARR[$i][$iCompare] < $usersARR[$i+1][$iCompare]) $rank = $count - $i; // Otherwise keep the same rank, because they are equal
$usersARR[$count - 1][$j] = $rank;
}
}
}
// Now $usersARR is filled with the correct rankings, and they are asscoiated with $UserId
// Now we must put all of these rankings into the database
$count = count($usersARR);
for($i = 0; $i < $count; $i++)
{
$stmt = $db->prepare("UPDATE studenttable SET AsyncPointsAverageRank=:AsyncPointsAverageRank, AsyncPointsRecentAverageRank=:AsyncPointsRecentAverageRank "
. "WHERE UserId=:UserId");
$stmt->execute(array(':AsyncPointsAverageRank' => $usersARR[$i][3],
':AsyncPointsRecentAverageRank' => $usersARR[$i][4],
':UserId' => $usersARR[$i][0]));
}
}
Bạn có thể sử dụng giao dịch và thực hiện tất cả các cập nhật. Tôi không chắc chắn nếu MyISAM hỗ trợ giao dịch nhưng InnoDb thì có. – frz3993
Mã của bạn được tiêm an toàn và chạy một nghìn truy vấn cập nhật nhỏ không có vấn đề gì đối với bất kỳ máy chủ cơ sở dữ liệu hiện đại nào. Tôi muốn nói bạn ổn. Nếu bạn muốn tối ưu hóa thêm, bạn đang ở trên trang web StackExchange sai. :) –
Không nhìn vào chi tiết cho vấn đề của bạn vì cách bạn làm nó có vẻ ổn nhưng chỉ vì "mục đích thảo luận", nếu bạn muốn tránh hàng nghìn bản cập nhật trong db của mình, bạn có thể xem xét một thứ hạng khác "hệ thống, giống như một cột trong bảng của bạn đề cập đến" trước đó "hoặc" yếu tố tiếp theo ". Bằng cách này, cập nhật xếp hạng của bạn sẽ chỉ ảnh hưởng đến các mục "được phân loại lại" và hàng xóm ... – Julo0sS