如何优化由于ORDER BY RAND()而导致的慢速MySQL查询?

时间:2011-10-31 22:48:37

标签: mysql database random

所以我有这个相对简单的查询来根据两个不同的MyISAM表中的一些条件来拉随机行:

SELECT 
    table1 . * , table2 . * 
FROM 
    Table1 AS table1
LEFT JOIN 
    Table2 AS table2
USING (
    col1
)
WHERE 
    table1.col1 !=  '5324372'
AND 
    table1.col2 LIKE  'S'
AND (
    table1.col3 LIKE  'I'
    OR table1.col3 LIKE  'V-G'
)
AND (
    table2.col1 =  'A'
    OR table2.col2 =  'B'
)
ORDER BY RAND( ) 
LIMIT 1

...一开始工作正常,但随着我的数据库开始增长,现在需要几秒钟才能执行。

上面使用的所有列都已编入索引,因此它不是索引问题。

根据我的研究,这是由于ORDER BY RAND()线显然在大型桌子上运行得很慢。

我已经看到了这个问题的一些潜在解决方案,但是它们非常神秘,我无法围绕上面的查询来解决任何问题。

我真的很惊讶MySQL没有针对这个非常慢的ORDER BY RAND()问题的内置解决方案,因为在我看来,对于需要选择a的许多类型的应用程序来说,这是一个非常基本的需求随机排。

那么我怎样才能优化上面的查询,以便在没有长执行时间的情况下获得相同/相似的效果?

2 个答案:

答案 0 :(得分:2)

排序通常是N * log(N)操作。通常,查询规划器/生成器/优化器通过将其与索引或子查询自然产生的顺序相结合,尽可能地避免排序。随机排序不能以任何方式“优化”。解决方案:不要这样做。

答案 1 :(得分:1)

您只选择一行,我认为您可以随机选择LIMIT随机选择一行。例如:

如果你有:

SELECT * table  ORDER BY RAND( )  LIMIT 1;

将其更改为

SELECT * table    LIMIT $randomvalue  ,$randomvalue + 1;

$ randomvalue是从应用程序级别中选择的随机值。

更新:以下答案比上述答案更清晰。

//get the total number of rows
$result= mysql_query(" SELECT  COUNT(*) AS total FROM `table` ");
$row = mysql_fetch_array($result);
$total=$row['total'];


//create random value from 1 to the total of rows 
$randomvalue =rand(1,$total);


//get the random row

$result= mysql_query(" SELECT  * FROM `table` limit $randomvalue,1");