我需要从一个表中获取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 |
但我也阅读了一些反对使用派生表的声明。
如果后一个问题有待改进,请告诉我吗?
答案 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行可供选择。