简体   繁体   English

如何使用SQL查询优化while循环?

[英]How to optimize while loop with SQL query?

$id = $user['id']; // the ID of the logged in user, we are retrieving his friends
$friends = $db->query("SELECT * FROM friend_requests WHERE accepted='1' AND (user1='".$id."' OR user2='".$id."') ORDER BY id DESC");

while($friend = $friends->fetch_array()) {
    $fr = $db->query("SELECT id,profile_picture,age,full_name,last_active FROM users WHERE (id='".$friend['user1']."' OR id='".$friend['user2']."') AND id != '".$id."'")->fetch_array(); 
    echo $fr['age'];     
}

I am basically looping through all my friends, and getting information about each one. 我基本上是遍历所有朋友,并获取有关每个朋友的信息。

How would I ago about optimizing this, I am aware that that it is inefficient to run this query so many times, considering there are thousands of "friends", but I'm not exactly sure how to go about optimizing it. 考虑到有成千上万的“朋友”,我如何优化该查询,我知道运行这么多次查询效率很低,但是我不确定如何优化它。 Any help is appreciated, thanks. 任何帮助表示赞赏,谢谢。

That article in the comments is great. 评论中的那篇文章很棒。 You're definitely going to want to figure out how to write the join yourself. 您肯定会想出如何自己编写联接的方法。 Here's my attempt at writing it for you. 这是我为您编写的尝试。 While you're rewriting the query, you might want to not * columns from friend_requests (or any at all since you're going to use the join). 在重写查询时,您可能不希望* *来自friend_requests的列(或者因为要使用联接而根本没有*)。 Any column you pull will have to be loaded into memory so any you can avoid pulling will help out. 您拉出的任何列都必须加载到内存中,因此可以避免的任何列都会有所帮助。 Especially if you're PHP server and your DB server are not on the same machine (less data over the network). 特别是如果您是PHP服务器,而您的DB服务器不在同一台计算机上(网络上的数据较少)。

Anyway, here's my shot in the dark: 无论如何,这是我在黑暗中的镜头:

$id = $user['id'];

$friends = $db->prepare("
    SELECT
        freq.* 
        ,users.id AS users_id
        ,users.profile_picture
        ,users.age
        ,users.full_name
        ,users.last_active
    FROM friend_requests freq
    INNER JOIN users u ON users.id IN (freq.user1,freq.user2) AND freq.id != u.id
    WHERE
        freq.accepted='1'
        AND ? IN (freq.user1,freq.user2
    ORDER BY freq.id DESC");
if($friends) {

    $friends->bindParam("s",$id);

    if($friends->execute()) {
        // get_result() only works if you have the MySQL native driver. 
        // You'll find out real quick if you don't
        $myFriends = $friends->get_result();

        while($row = $myFriends->fetch_assoc()) {
            echo $row['age'];     
        }
    }
}
else {
    printf("SQL Error: %s.<br>\n", $friends->error);
}
// cleanup
$friends->close();

quick reference: get_result() 快速参考: get_result()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM