为啥添加 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 过载?的主要内容,如果未能解决你的问题,请参考以下文章
为啥vector会导致Segmentation fault Error?