我应该在这种情况下使用派生表吗?

时间:2014-04-15 21:08:00

标签: mysql sql

我需要从一个表中获取10个随机行,下面的查询不会这样做,因为它会在很大程度上变得非常慢(我已经阅读了强有力的参数):

SELECT `title` FROM table1 WHERE id1 = 10527 and id2 = 37821 ORDER BY RAND() LIMIT 10;

EXPLAIN:
select_type |    table    | type | possible_keys |  key  | key_len | ref  | rows | Extra          |
------------+-------------+------+---------------+-------+---------+------+------+----------------+ 
SIMPLE      |  table1     |  ref | id1,id2       |  id2  | 5       | const|  7   | Using where; Using temporary; Using filesort

我尝试了以下解决方法:

SELECT * FROM
(SELECT `title`, RAND() as n1
FROM table1
WHERE id1 = 10527 and id2 = 37821) TTA
ORDER BY n1 LIMIT 10;

EXPLAIN:
select_type |    table    | type | possible_keys |  key  | key_len | ref  | rows | Extra          |
------------+-------------+------+---------------+-------+---------+------+------+----------------+ 
PRIMARY     |  <derived2> |  ALL | NULL          |  NULL | NULL    | NULL |  7   | Using filesort |
DERIVED     |    table1   |  ref | id1,id2       |  id2  |   5     |const |  7   | Using where    |

但我也阅读了一些反对使用派生表的声明。

如果后一个问题有待改进,请告诉我吗?

1 个答案:

答案 0 :(得分:1)

您应该尝试第一种方法,看看它是否适合您。如果您在table1(id1, id2) 上有索引,那么任何给定值对的出现次数都不会很多,那么性能可能很适合您想要做的事情。

您的第二个查询的性能会比第一个查询差一些。 order by rand()的效果问题是计算随机数所需的时间。问题是order by,你的第二个查询基本上做了同样的事情,带来了派生表的额外开销。

如果你知道总有至少1000个匹配值,那么以下通常工作得更快:

SELECT `title`
FROM table1
WHERE id1 = 10527 and id2 = 37821 and rand() < 0.05
ORDER BY RAND()
LIMIT 10;

这将采用大约5%数据的随机样本,并且有1,000个匹配的行,您几乎总是至少有10行可供选择。