MySQL中的随机抽取如何实现
1. 引言
现在有一个需求是从一个单词表中每次随机选取三个单词。
这个表的建表语句和如下所示:
mysql> Create table 'words'( 'id' int(11) not null auto_increment; 'word' varchar(64) default null; primary key ('id') ) ENGINE=InnoDB;
然后我们向其中插入10000行数据。接下来我们看看如何从中随机选择3个单词。
2. 内存临时表
首先,我们通常会想到用order by rand()来实现这个逻辑:
mysql> select word from words order by rand() limit 3;
虽然这句话很简单,但是执行流程则比较复杂。我们使用explain来看看语句的执行情况:
Extra字段中Using temporary表示需要使用临时表,Using filesort表示需要进行排序。也就是需要进行排序操作。
对于InnoDB表来说,执行全字段排序能够减少对于磁盘的访问,所以会被优先选择。
而对于内存表来说,回表过程只是简单地根据数据行的位置,直接访问内存得到数据,根本不会导致多访问磁盘。所以这时MySQL会优选选择rowid排序。
我们接下来再来梳理下这条语句的执行流程:
创建一个临时表,这个表使用memory引擎,表里有两个字段,第一个字段是double类型,记为R,第二个字段是varchar(64)类型,记为W。并且这个表没有索引。
从words表中,按主键顺序取出所有的word。对于每个word,调用rand()函数随机生成一个大于0小于1的随机小数,并把这个随机小数和word分别存入临时表的R和W字段中。
接下来就是按照字段R进行排序
初始化sort_buffer。sort_buffer包括一个double类型和一个整型字段。
从内存临时表中一行行取出R值和位置信息,分别存入sort_buffer的两个字段里。
sort_buffer按照R值进行排序
排序完成后,取出前三个结果的位置信息,到内存临时表中取出相应的word,返回给客户端。
流程示意图如下所示:
上面讲的位置信息,其实就是行所在的位置,也就是我们之前说的rowid。
对于InnoDB引擎来说,对于有没有主键表来说有两种处理方式:
对于有主键的InnoDB表来说,这个rowid就是主键id
对于没有主键的InnoDB表来说,这个rowid是由系统生成的,用来标识不同行。
因此,order by randn()使用了内存临时表,内存临时表的排序方法用的是rowid排序方法。
3. 磁盘临时表
不是所有的临时表都是内存临时表。tmp_table_size这个配置限制了内存临时表的大小,如果超过了这个大小,就会使用磁盘临时表。InnoDB引擎就是默认使用磁盘临时表。
4. 优先队列排序算法
在MySQL5.6之后,引入了优先队列排序算法,这种算法是不需要使用临时文件的。而原本的归并排序算法则是需要使用临时文件。
因为当你使用归并算法的时候,其实你只需要得到前3,但是你是用完归并排序,那已经整体有序了,造成了资源的浪费。
而优先队列排序算法则可以只取到前三,执行流程如下:
对于这10000个准备排序的(R,rowid),先取前三行,构造成一个堆,并且将最大的值放在堆顶;
取下一行(R’,rowid’),跟当前堆里面最大的R比较,如果R’小于R,则把(R,rowid)从堆中去掉,换成(R’,rowid’)。
不断重复上面的过程。
流程如下图所示:
但是当limit的数比较大时,维护堆比较困难,所以又会使用归并排序算法。
以上是MySQL中的随机抽取如何实现的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

可以通过以下步骤打开 phpMyAdmin:1. 登录网站控制面板;2. 找到并点击 phpMyAdmin 图标;3. 输入 MySQL 凭据;4. 点击 "登录"。

MySQL是一种开源的关系型数据库管理系统,主要用于快速、可靠地存储和检索数据。其工作原理包括客户端请求、查询解析、执行查询和返回结果。使用示例包括创建表、插入和查询数据,以及高级功能如JOIN操作。常见错误涉及SQL语法、数据类型和权限问题,优化建议包括使用索引、优化查询和分表分区。

MySQL在数据库和编程中的地位非常重要,它是一个开源的关系型数据库管理系统,广泛应用于各种应用场景。1)MySQL提供高效的数据存储、组织和检索功能,支持Web、移动和企业级系统。2)它使用客户端-服务器架构,支持多种存储引擎和索引优化。3)基本用法包括创建表和插入数据,高级用法涉及多表JOIN和复杂查询。4)常见问题如SQL语法错误和性能问题可以通过EXPLAIN命令和慢查询日志调试。5)性能优化方法包括合理使用索引、优化查询和使用缓存,最佳实践包括使用事务和PreparedStatemen

选择MySQL的原因是其性能、可靠性、易用性和社区支持。1.MySQL提供高效的数据存储和检索功能,支持多种数据类型和高级查询操作。2.采用客户端-服务器架构和多种存储引擎,支持事务和查询优化。3.易于使用,支持多种操作系统和编程语言。4.拥有强大的社区支持,提供丰富的资源和解决方案。

Apache 连接数据库需要以下步骤:安装数据库驱动程序。配置 web.xml 文件以创建连接池。创建 JDBC 数据源,指定连接设置。从 Java 代码中使用 JDBC API 访问数据库,包括获取连接、创建语句、绑定参数、执行查询或更新以及处理结果。

在 Docker 中启动 MySQL 的过程包含以下步骤:拉取 MySQL 镜像创建并启动容器,设置根用户密码并映射端口验证连接创建数据库和用户授予对数据库的所有权限

MySQL在Web应用中的主要作用是存储和管理数据。1.MySQL高效处理用户信息、产品目录和交易记录等数据。2.通过SQL查询,开发者能从数据库提取信息生成动态内容。3.MySQL基于客户端-服务器模型工作,确保查询速度可接受。

在 CentOS 上安装 MySQL 涉及以下步骤:添加合适的 MySQL yum 源。执行 yum install mysql-server 命令以安装 MySQL 服务器。使用 mysql_secure_installation 命令进行安全设置,例如设置 root 用户密码。根据需要自定义 MySQL 配置文件。调整 MySQL 参数和优化数据库以提升性能。
