mysql随机排序

2020-02-13 13:37:53

参考地址 mysql随机排序

需求:首页热门栏目需要随机显示几条信息


方案1:order by rand(),全表扫描


SELECT SQL_NO_CACHE * FROM `house_rent` order by rand() limit 10

(共 1 行, 查询花费 0.1069秒)

explain SELECT * FROM `house_rent` order by rand() limit 1

id   select_type       table          type       possible_keys   key      key_len        ref         rows                           Extra

1       SIMPLE     house_rent    ALL                NULL       NULL       NULL      NULL      1009   Using temporary; Using filesort


方案2:拆分两个sql语句,第一个先随机取得id,可以用到index索引,第二个根据这些id直接定位。总用时0.0021,单需要两次请求


SELECT SQL_NO_CACHE id FROM `house_rent` order by rand() limit 10 

(共 1 行, 查询花费 0.0012 秒)

explain SELECT id FROM `house_rent` order by rand() limit 10 

id   select_type       table          type       possible_keys   key      key_len        ref         rows                           Extra 

1       SIMPLE     house_rent    index             NULL             uid             5             NULL     1690    Using index; Using temporary; Using filesort


SELECT SQL_NO_CACHE * FROM `house_rent` where id in (298,106,533,545,2,446,1367,1509,759,499)

(共 10 行, 查询花费 0.0009 秒)


方案3:将方案2两次请求用子查询合并为一次,查询时间比方案2高5倍,可见效果并不好,为了满足mysql语法生成了2张临时表。但是这种子查询并没有引发了笛卡尔积


SELECT SQL_NO_CACHE * FROM `house_rent` where id in ( select id from (SELECT id FROM `house_rent` order by rand() limit 10 ) as a )

(共 10 行, 查询花费 0.0110 秒)

SELECT SQL_NO_CACHE * FROM `house_rent` where id in ( select id from (SELECT id FROM `house_rent` order by rand() limit 50 ) as a )

(共 50 行, 查询花费 0.0071 秒)


方案4:利用子查询先计算一个随机点,然后再取小于该随机点的n条数据,因为取值是连贯的,所以速度比较快。而且子查询语句是纯数学计算,也不会有临时表影响。此方案虽然结果是连续的几个值,但每次获取的内容不一样,可以满足需求


select SQL_NO_CACHE * from house_rent where status=1 and cid=4 and (select ceil(rand()*(select MAX( id ) from house_rent)))<=id limit 10

(共 10 行, 查询花费 0.0011 秒)




explain select SQL_NO_CACHE * from house_rent where status=1 and cid=4 and (select ceil(rand()*(select MAX( id ) from house_rent)))<=id limit 10

id   select_type       table                 type       possible_keys   key      key_len        ref         rows                           Extra 

1      PRIMARY       house_rent       ref            status             status          2             const     1478                Using where

3     SUBQUERY        NULL          NULL         NULL                NULL       NULL       NULL     NULL     Select tables optimized away


  • 2019-07-23 14:49:40

    Windows10上使用Linux子系统(WSL)

    Linux的Windows子系统让开发人员可以直接在Windows上运行Linux环境(包括大多数命令行工具,实用程序和应用程序),而无需建立在虚拟机的开销之上,整个系统共200多M,但包含了你能用到的所有功能,并且和windows完美互操作(省去linux挂载本地windows分区或目录的操作),目前Linux的windows子系统已经相当完善,可当作完整linux系统使用

  • 2019-07-24 01:21:15

    android开发无障碍app

    最近做一些为盲人提供服务的APP,还是挺有感触的,感谢手机和互联网的普及,他们的生活比以前丰富了很多。 通过读屏软件,盲人可以操作手机,上网浏览信息。读屏软件的工作原理很简单,就是读出屏幕上按钮、文本的信息。

  • 2019-07-26 19:31:03

    Guacamole搭建

    因项目需要,经历多天查阅各种文档,几经波折终于功德圆满,写下此篇文章供大家分享。Guacamole就个人理解而言是一个可以通过web浏览器访问远程服务器终端进行操作的可视化工具。主要由web(浏览器)、Guacamole Server(核心)、Remote Desktops(远程桌面)三大模块组成。

  • 2019-07-30 22:36:10

    使用 Spring Initializr 初始化 Spring Boot 项目

    万事开头难,你需要设置一个目录结构存放各种项目内容,创建构建文件,并在其中加入各 种依赖。Spring Boot CLI消除了不少设置工作,但如果你更倾向于传统Java项目结构,那你应该 看看Spring Initializr。

  • 2019-08-06 15:30:08

    小程序展示富文本

    然而rich-text有个问题,它不能够给内联img设置宽度100%,这样图片就容易溢出屏幕。我们只能在后台返回富文本的时候对图片的img标签进行格式化。或者前端进行格式化也行,我赞成使用后端,因为很多种情况我们不一定都能想得到。

  • 2019-08-07 09:07:32

    最全的Service Worker讲解

    Service Worker 最主要的特点是:在页面中注册并安装成功后,运行于浏览器后台,不受页面刷新的影响,可以监听和截拦作用域范围内所有页面的 HTTP 请求。 基于 Service Worker API 的特性,结合 Fetch API、Cache API、Push API、postMessage API 和 Notification API,可以在基于浏览器的 web 应用中实现如离线缓存、消息推送、静默更新等 native 应用常见的功能,以给 web 应用提供更好更丰富的使用体验。