ORDER BY RAND导致非常高的负载

时间:2014-01-20 10:59:50

标签: php sql

我有以下查询

$samecars = $this->QueryResult("SELECT * FROM carads where STATUS='1' and DEL='0' 
and TITLE !='' and IMAGE1 != '' and IMAGE1 != '-1' and PRICE BETWEEN $pricelow 
and $pricehigh order by RAND() LIMIT 0,3");

当我删除RAND()时,查询几乎立即执行,如果我添加RAND()则需要大约10-30秒。

表carads中大约有100万行。 我需要RAND()才能使用随机显示。

更多详情:

QueryResult看起来像这样

public function QueryResult($strQuery) {
    $this->connector();
    $query = mysqli_query($this->link, $strQuery);
    $arr = array();
    if ($query) {
        while ($result = mysqli_fetch_object($query)) {
            array_push($arr, $result);
        }
    }
    $this->close();
    return $arr;
}

我尝试在SQL中添加以下示例命令

SELECT * FROM carads where STATUS='1' and DEL='0' 
and TITLE !='' and IMAGE1 != '' and IMAGE1 != '-1' and PRICE BETWEEN 8000 
and 15000 order by RAND() LIMIT 0,3"

和RAND()以红色突出显示,当我通过#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"' at line 3

执行时

2 个答案:

答案 0 :(得分:3)

<强> 1。俄罗斯轮盘赌抽样

RAND()导致问题的原因是因为查询了表的所有行而不是例如前三行。排序需要一些时间。

加快处理速度的想法是使用俄罗斯轮盘抽样:

SELECT * FROM carads where STATUS='1' and DEL='0' and TITLE !='' and IMAGE1 != '' and IMAGE1 != '-1' and PRICE BETWEEN $pricelow and $pricehigh AND RAND() < 0.001 LIMIT 0,3

其中0.001相当小。这种方法的问题是不会统一挑选物品(第一件物品有更多机会)。此外,概率应取决于表格的大小(因此偶尔,管理工具应重新计算概率)。然而,这是解决问题的实用方法。

<强> 2。 PHP完成(大部分)工作

由于只有三行,您可以执行以下过程:

  1. 首先查询数据库以查找行数
  2. 在0和行数(不包括)之间生成三个不同的随机数
  3. 查询三行并处理数据。

答案 1 :(得分:0)

查询执行缓慢的另一个原因是当使用像rand(),时间函数等等的聚合函数时...阻止查询被缓存。所以一个好的做法是尝试不在SQL查询中使用这些函数,并使用php传递它:

$query = "SELECT * FROM table order by " . rand();

而不是

$query = "SELECT * FROM table order by RAND()";

希望它有用。

此致