mysql优化--rand()优化

众所周知,在mysql中,随机的取10条数据,如:select * from users order by rand() limit 10,效果非常差,因为会多次的执行,如果等值查询用rand()也是效很差,

1.select id from users where id =111;

看查询计划可以得到,是是常量查询,而且是索引覆盖,速度非常快!

2.使用rand(),求随机数后检索

select id from users where id=round(rand()*1000);

执行计划很糟糕,虽然是扫描了索引,但是是全索引的扫描,很差,因为where条件中包含了rand(),使得mysql把它当做变量来处理。无法用常量的等值查询。

3.改造成普通的子查询

select id from users where id =(select round(rand()*(select max(id) from users)) as nid)

查询计划也不好!(子查询会全表扫描)

4.改成join联表

select id from users as us inner join (select round(rand()*1000) as id2) as t2 on t2.id2=us.id

这样的执行计划就很好了,速度也很快

小结:从数据库随机的取一条数据时候,可以把rand()生成的随机数放到join中提高效率。

5.order by rand() limit n 

随机取多条的时候

全索引扫描,生成排序临时表,文件排序,很慢!

6.仿照join方式

select id from users as us inner join (select round(rand()*(select max(id) from users)) as ids) as t1 on us.id>t1.ids limit n

全索引检索,发现符合记录的条件后,直接取10行,这个方法是最快的。

PS:综上:

    想从mysql数据库里随机的取一条或者多条时,最好把rand生成的随机数放到join子句中,提高查询效率。

就是把这个sql:

      select id from table order by rand() limit n;

变成这个sql:

select id from table t1 join (select round(rand()*(select max(id ) from table)) as idd) as t2 on t1.id>t2.idd limit n;

 

posted @ 2016-10-24 19:20  tianye_guazi  阅读(2986)  评论(0编辑  收藏  举报