为啥添加 RAND() 会导致 MySQL 过载?

Posted

技术标签:

【中文标题】为啥添加 RAND() 会导致 MySQL 过载?【英文标题】:Why does added RAND() cause MySQL to overload?为什么添加 RAND() 会导致 MySQL 过载? 【发布时间】:2010-01-05 20:59:38 【问题描述】:

好的,我有这个查询,它给了我 DISTINCT product_series,加上表中的所有其他字段:

SELECT  pi.*
FROM    (
        SELECT  DISTINCT product_series 
        FROM    cart_product 
        ) pd
JOIN    cart_product  pi
ON      pi.product_id =
        (
        SELECT  product_id
        FROM    cart_product po
        WHERE   product_brand = "everlon" 
                AND product_type = "'.$type.'" 
                AND product_available = "yes"
                AND product_price_contact = "no"
                AND product_series != ""
                AND po.product_series = pd.product_series
        ORDER BY product_price
        LIMIT 1
        ) ORDER BY product_price

这很好用。我也是按价格订购的,所以我可以获得每个系列的起始价格。不错。

但是今天我的老板告诉我,这个查询中显示的所有产品都是metal_type 白金,他想显示随机金属类型。所以我在 ORDER BY 价格之后将 RAND() 添加到 order by 中,这样我仍然会得到最低价格,但是最低价格的随机金属.. 这是新的查询:

SELECT  pi.*
FROM    (
        SELECT  DISTINCT product_series 
        FROM    cart_product 
        ) pd
JOIN    cart_product  pi
ON      pi.product_id =
        (
        SELECT  product_id
        FROM    cart_product po
        WHERE   product_brand = "everlon" 
                AND product_type = "'.$type.'" 
                AND product_available = "yes"
                AND product_price_contact = "no"
                AND product_series != ""
                AND po.product_series = pd.product_series
        ORDER BY product_price, RAND()
        LIMIT 1
        ) ORDER BY product_price, RAND()

当我运行这个查询时,mysql 完全关闭并告诉我有连接太多我接到主机管理员的电话,问我到底做了什么。

我不相信这可能只是将 RAND() 添加到查询中,我认为这一定是巧合。一切都修复后,我等了几个小时,然后再次运行查询。马上...同样的问题。

那么发生了什么?因为我没有头绪。我的查询有问题吗?

谢谢!!!!

【问题讨论】:

不能解决您的问题,但您确实应该使用查询参数而不是字符串连接。 @Mark,你能给我或给我一个例子吗?谢谢。 @John: ***.com/questions/60174/… 【参考方案1】:

ORDER BY 使用 RAND() 不是一个好主意,因为它不会随着数据的增加而扩展。您可以在我对this question 的回答中查看更多信息,包括您可以调整的两种替代方案。

【讨论】:

【参考方案2】:

这里有一篇博文很好地解释了这个问题,以及解决方法:

http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/

这是针对 MySQL 的 ORDER BY RAND() 的类似警告,我认为原因基本相同:

http://www.webtrenches.com/post.cfm/avoid-rand-in-mysql

【讨论】:

这是另一个博客,提供各种解决方案:jan.kneschke.de/projects/mysql/order-by-rand【参考方案3】:

根据您网站中的产品数量,该函数调用将在每条记录中执行一次,这可能会大大减慢查询速度。

Too Many Connections 错误可能是由于此查询在尝试计算这些数字时阻塞了其他查询。

另辟蹊径。 ;)

【讨论】:

【参考方案4】:

相反,您可以在您使用的编程语言上生成随机数,而不是在 MySQL 端,因为每行都会调用 rand()

【讨论】:

【参考方案5】:

如果你知道你有多少条记录,你可以像这样选择一个随机记录(这是 Perl):

$handle->Sql("SELECT COUNT(0) AS nor FROM table");
$handle->FetchRow();
$nor = $handle->Data('nor');
$rand = int(rand()*$nor)+1;
$handle->Sql("SELECT * FROM table LIMIT $rand,1");
$handle->FetchRow();
.
.
.

【讨论】:

以上是关于为啥添加 RAND() 会导致 MySQL 过载?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 MySQL 查询中添加 '*' 会导致语法错误?

为啥 rand() + rand() 会产生负数?

为啥vector会导致Segmentation fault Error?

为啥使用 scipy 保存 mat 文件会导致文件大小比使用 Matlab 大?

mysql随机获取一条或者多条数据

mysql order by rand() 性能问题及解决方案