MySQL“无索引连接”计数器正在递增,如mysql-tuner.pl等各种分析工具所示,跟踪到使用RAND()选择随机产品的查询,我想优化以帮助避免这个增量。
查询如下所示:
select p.*, count(u.prodid) as count from prods p
left outer join usage u on p.prodid=u.prodid
where p.ownerid>0 and p.active=1
group by p.prodid
order by rand() limit 1;
我也尝试过使用这种风格......
select p.*, count(u.prodid) as count from prods p
left outer join usage u on p.prodid=u.prodid
where prodid in
(select prodid from prods
where ownerid>0 and active=1
group by prodid order by rand() limit 1);
但MySQL不支持'in'子查询中的LIMIT ...
解释/描述看起来像这样......
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
| 1 | SIMPLE | p | range | ownerid | ownerid | 4 | NULL | 11 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | u | index | NULL | userid | 8 | NULL | 52 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
2行(0.00秒)
虽然你们中的一些人可能会认为“如果它执行无索引连接会怎么样”,也许这可能比一个问题更令人烦恼,但我很欣赏可能有更好的方法来实现所需要的东西。特别是当表行计数增长时......
所以欢迎任何想法!
答案 0 :(得分:1)
通常运行多个查询比通过rand()
对表进行排序更快。首先得到行的随机数:
select floor( count(*) * rand() ) random_number
from prods
where ownerid > 0 and active = 1
然后得到特定的行:
select p.*, count(u.prodid) as count
from prods p
left outer join usage u on p.prodid = u.prodid
where prodid = (
select prodid from prods
where ownerid > 0 and active = 1
limit {$random_number}, 1
)
顺便说一下,子查询只返回一个字段,因此您可以使用=
代替in
运算符。