从mysqli预处理语句中选择随机行

时间:2014-03-26 21:03:12

标签: php

我正在研究MYSQL表中的随机选择。我发现ORDER BY RAND()在较大的数据库上非常慢。我正在尝试使用不同的方法,但是在返回时我一直得到一个空查询。我不习惯AS声明,所以我的代码可能有问题吗?

public function getSmilies( $limit = null, $random = null )
{
    $query = "SELECT find, url, id FROM smilies";
    if($random == 1)
    {
        $query .= " AS r1 JOIN (SELECT (RAND() * (SELECT MAX(id) FROM smilies)) AS id) AS r2 WHERE r1.id >= r2.id ORDER BY r1.id ASC";
    }
    if($limit != null)
    {
        $query .= " LIMIT " . (int)$limit;
    }

    $stmt = $this->link->prepare($query);
    $stmt->execute();
    $stmt->bind_result( $find, $url, $id );
    while($stmt->fetch())
        $row[] = array('find' => $find, 'url' => $url, 'id' => $id );
    $stmt->close();
    return $row;
}

当没有参数传递给函数时,代码工作正常,但是当我添加随机参数时,它似乎失败了。

1 个答案:

答案 0 :(得分:2)

MySQL查询:

SELECT * FROM smilies WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM smilies ) LIMIT 5;

完整的PHP代码:

public function getSmilies( $limit = null, $random = null )
{
    $query = "SELECT find, url, id FROM smilies";
    if($random == 1)
    {
        $query .= " WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM smilies)";
    }
    if($limit != null)
    {
        $query .= " LIMIT " . (int)$limit;
    }

    $stmt = $this->link->prepare($query);
    $stmt->execute();
    $stmt->bind_result( $find, $url, $id );
    while($stmt->fetch())
        $row[] = array('find' => $find, 'url' => $url, 'id' => $id );
    $stmt->close();
    return $row;
}

注1:这仅适用于唯一的ID 注2:仅测试了MySQL查询,而不是PHP代码 来源:http://akinas.com/pages/en/blog/mysql_random_row/(解决方案3)

编辑:使用PHP的另一种选择。

public function getSmilies( $limit = null, $random = null )
{
    $query = "SELECT find, url, id FROM smilies";
    if($limit != null)
    {
        $query .= " LIMIT " . (int)$limit;
    }
    $stmt = $this->link->prepare($query);
    $stmt->execute();
    $stmt->bind_result( $find, $url, $id );
    while($stmt->fetch())
        $row[] = array('find' => $find, 'url' => $url, 'id' => $id );
    $stmt->close();
    if($random == 1)
    {
        suffle($row);
    }
    return $row;
}