1

在我从事这个项目之前,我从来不需要在 MySQL 数据库上进行随机 SELECT。经过研究,似乎普通民众说使用 RAND() 是一个坏主意。我发现一篇文章解释了如何进行另一种随机选择。

基本上,如果我想选择五 (5) 个随机元素,我应该执行以下操作(我在这里使用的是 Kohana 框架)?

<?php
final class Offers extends Model
{
    /**
     * Loads a random set of offers.
     *
     * @param  integer  $limit
     * @return array
     */
    public function random_offers($limit = 5)
    {
        // Find the highest offer_id
        $sql = '
            SELECT MAX(offer_id) AS max_offer_id
              FROM offers
        ';
        $max_offer_id = DB::query(Database::SELECT, $sql)
            ->execute($this->_db)
            ->get('max_offer_id');

        // Check to make sure we're not trying to load more offers
        // than there really is...
        if ($max_offer_id < $limit)
        {
            $limit = $max_offer_id;
        }

        $used = array();
        $ids = '';
        for ($i = 0; $i < $limit; )
        {
            $rand = mt_rand(1, $max_offer_id);
            if (!isset($used[$rand]))
            {
                // Flag the ID as used
                $used[$rand] = TRUE;

                // Set the ID
                if ($i > 0) $ids .= ',';
                $ids .= $rand;

                ++$i;
            }
        }

        $sql = '
            SELECT offer_id, offer_name
              FROM offers
             WHERE offer_id IN(:ids)
        ';
        $offers = DB::query(Database::SELECT, $sql)
            ->param(':ids', $ids)
            ->as_object();
            ->execute($this->_db);

        return $offers;
    }
}

如果没有,有什么更好的解决方案?

4

2 回答 2

5

只要您的 offer_id 是连续的且连续的,这种方法就可以工作 - 如果您曾经删除过一个 offer,那么您的 id 中可能会出现问题,这将是一个问题。

于 2010-05-06T03:44:01.183 回答
0

我已经在大型表集上阅读了有关 MySQL rand() 函数的相同内容,但我认为您可以通过计算表行数来更快地做到这一点,然后使用 PHP 内置的 rand(0, count) 生成一些索引您可以在 SELECT 中获取 ID。我怀疑它会产生相同的影响,但没有所有性能问题。

于 2010-05-06T03:44:08.177 回答