前言

可能许多小伙伴在面试中会遇到这么样的一道面试题:如何以最高效率随机在 Mysql 数据表中查找一条数据

实际上,这个题包含了两个点

  • 在 Mysql 数据表随机查找一条数据

  • 保证效率最高

实战

我们平时常用的英语App,大部分都有 随机显示一个单词或者多个单词的功能,为了便于理解,我设计了以下代码,并往表里加了 30000 行数据。

CREATE TABLE `words` (`id` int(11) NOT NULL AUTO_INCREMENT,`word` varchar(64) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB;delimiter ;;
create procedure idata()
begindeclare i int;set i=0;while i<30000 doinsert into words(word) values(concat(char(97+(i div 1000)), char(97+(i % 1000 div 100)), char(97+(i % 100 div 10)), char(97+(i % 10))));set i=i+1;end while;
end;;
delimiter ;call idata();

方法一

随机查找,你可能会想到最原始最直观的方法,使用 Mysqlrand() 方法

select * from words order by rand() limit 1;

使用 explain 查看执行计划,可以发现使用 rand() ,Extra字段显示 Using temporary,表示的是需要使用临时表;Using filesort,表示的是需要执行排序操作。因此这个 Extra 的意思就是,需要临时表,并且需要在临时表上排序。

我们的 Mysql 使用 InnoDB存储引擎,对于 InnoDB 的数据表来说,执行全字段排序会减少磁盘访问,因此会被优先选择。但是,对于内存表,回表过程只是简单地根据数据行的位置,直接访问内存得到数据,根本不会导致多访问磁盘。优化器没有了这一层顾虑,那么它会优先考虑的,就是用于排序的行越少越好了,所以,MySQL这时就会选择 rowid 排序,排序临时表。

也就是说,order by rand() 使用了内存临时表,内存临时表排序的时候使用了 rowid 排序方法(Using temporaryUsing filesort),查询的执行代价往往是比较大的。所以,在设计的时候,我们需要尽量避开这种写法。

方法二

思路大概如下:

  • 取得这个表的主键 id 的最大值 M 和最小值 N ;

    首先查询出数据表的所有记录数

select count(*) as num_rows from words;
  • 用随机函数生成一个最大值到最小值之间的数 X = (M-N)*rand() + N;
  • 取不小于X的第一个 ID 的行。

然后在 [0, num_rows] 范围中随机

select * from words limit [0, num_rows随机一个数X], 1;

方法三

那有没有可能,一句 sql 就完成 方法二 的查询,那当然是有的,SQL 如下:

SELECT * FROM  `words` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM  `words`)-(SELECT MIN(id) FROM `words`))+(SELECT MIN(id) FROM `words`))  AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id LIMIT 1;

当然,上述的 sql 有一个问题,如果要快速随机查询多条数据,修改上述的语句 limit nn 代表 n 条数据如修改成 limit 5,那么就会产生连续的 5 条记录。解决办法只能是每次查询一条,查询 5。次。

当然,上述的问题可以使用以下方法解决。

SELECT * FROM `words`
WHERE id >= (SELECT floor( RAND() * ((SELECT MAX(id) FROM  `words`)-(SELECT MIN(id) FROM `words`)) + (SELECT MIN(id) FROM  `words`)))
ORDER BY id LIMIT 5;

参考博客:

https://jishuin.proginn.com/p/763bfbd308d8

如何从Mysql快速查找一条数据相关推荐

  1. java mysql 快速插入1000w条数据_教你88秒插入1000万条数据到mysql数据库表

    我用到的数据库为,mysql数据库5.7版本的 1.首先自己准备好数据库表 其实我在插入1000万条数据的时候遇到了一些问题,现在先来解决他们,一开始我插入100万条数据时候报错,控制台的信息如下: ...

  2. Mysql中一千万条数据怎么快速查询

    文章来源: 学习通http://www.bdgxy.com/ 目录 普通分页查询 如何优化 偏移量大 采用id限定方式 优化数据量大问题 普通分页查询 当我们在日常工作中遇到大数据查询的时候,第一反应 ...

  3. mysql查询两张表的同一列_如何快速查找两个数据表之间的相同和不同?

    原标题:如何快速查找两个数据表之间的相同和不同? 知识 随笔 案例 声音 其他 编者按 工作中经常会遇到对来源不同的数据进行比对,查找相同.不同.差异性等.过于复杂的需求,我们通常会转换思路,使用数据 ...

  4. 百万条数据插入mysql_mysql快速插入百万条数据

    作者:在赤道吃冰棍儿 www.jianshu.com/p/36b87cb3a05a 前言 假设现在我们要向mysql插入500万条数据,如何实现高效快速的插入进去?暂时不考虑数据的获取.网络I/O.以 ...

  5. mysql快速生成100W条测试数据(8)全球各城市人口及经济增长速度并存入mysql数据库

    这是之前的文章里面包含一些以前的一些操作流程可以进行参考学习 更加详细操作步骤在第一篇文章里面 mysql快速生成100W条测试数据(1):游戏人物数据 mysql快速生成100W条测试数据(2)公司 ...

  6. mysql插10万条数据_MySQL数据库插入100w条数据要花多久?

    MySQL数据库插入100w条数据要花多久? 1.多线程插入(单表) 2.多线程插入(多表) 3.预处理SQL 4.多值插入SQL 5.事务(N条提交一次) # 多线程插入(单表) 问:为何对同一个表 ...

  7. MySql查询随机几条数据

    MySql查询随机几条数据 想到了  Max  RAND  这几个函数 用以下2种办法都可以实现查询.  速度还行. 我的 IT技术资源库   http://www.itlib.tk/ 几十万数据左右 ...

  8. 使用sql语句往MySQL插入1000万条数据

    在学习或者工作生产环境中,我们经常要对数据库进行压力测试,往数据库中批量插入大量数据,这里我往Mysql中批量插入大量数据,采用存储过程的方法实现. 数据库版本:Mysql5.7 一.建表 1.创建数 ...

  9. 插入2万调数据耗时_教你如何6秒钟往MySQL插入100万条数据!然后删库跑路!

    一.思路 往MySQL中插入1000000条数据只花了6秒钟! 关键点: 1.使用PreparedStatement对象 2.rewriteBatchedStatements=true 开启批量插入, ...

最新文章

  1. eclipse安装springtoolsuite-4-4.8.1失败,是eclipse版本不匹配吗
  2. 从城市大脑到世界数字大脑 构建人类协同发展的超级智能平台
  3. openstack中RemoteError: AgentNotFoundByTypeHost解决
  4. 算法之道:形而之上谓之道
  5. s5pv210——串口(UART)通信实战
  6. python读取mysql数据_Selenium(Python) ddt读取MySQL数据驱动
  7. SwitchResX Mac屏幕分辨率调整工具
  8. 链接数据库超级简单的工具类C3P0谁用谁知道
  9. 彻底关闭360安全卫士弹窗广告方法
  10. 替罪羊树——平衡二叉树
  11. 《神经网络与深度学习》基础篇
  12. 读取和修改JPEG图片文件的头信息EXIF和JFIF
  13. 微信小程序-加载图片
  14. 如何应对工作中的冲突?
  15. python统计英语单词出现次数
  16. iphone4S 怎么激活?
  17. 长生不老:从秦始皇到基因编辑
  18. Linux服务篇--LAMP架构
  19. Prim算法最小生成树Java超详解
  20. SQL数据库权限禁止授予deny

热门文章

  1. 网页进服务器,如何通过网页进去云服务器
  2. 以下python语言关键字在异常处理_python后端开发工程师考证试题
  3. 01: 网络参考模型 、 数据封装与传输 、 数制与数制转换 、 IP地址与子网掩码
  4. CSS-Learning | 使用border-radius创建圆形和胶囊形状(长圆形)
  5. 洛谷 P1873 砍树 (二分答案)
  6. 读后感:【许岑—如何成为有效学习的高手】
  7. LeetCode162数组寻峰问题
  8. vue时间格式2021-11-21T12:30:00.000+00:00转换yyyy-MM-dd HH:mm:ss
  9. 香港主机如何设置网站404页面
  10. 百度云盘转存阿里云盘工具下载