如何正确地显示随机消息?读后总结

2024-09-01 21:38

本文主要是介绍如何正确地显示随机消息?读后总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景:有个单词表,随机显示3个单词
建表语句与初始化语句
mysql> CREATE TABLE words (
id int(11) NOT NULL AUTO_INCREMENT,
word varchar(64) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;

delimiter ;;
create procedure idata()
begin
declare i int;
set i=0;
while i<10000 do
insert 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();

随机显示3个单词用什么sql
一般可能会用到的 order by rand()
select word from words order by rand() limit 3;
我们用explain查询语句执行。
关注extra字段using temporary表示使用临时表,using filesort表示需要执行排序。

对于内存临时表的排序来说,(PS:内存临时表的默认引擎是memory)
innodb为了减少磁盘的访问,优先选择全字段排序
内存表memory回表无须访问磁盘,优先选择rowid排序。

语句执行流程:

  1. 创建临时表,引擎为memory,有R,W两个字段,没有建索引
    2.从words表中,俺主键顺序取出所有的word值,对于每一个word值,调用rand()函数生成一个大于0小于1的随机小数。把随机小数与word存入临时表的RW字段
    3.临时表安装R字段排序。
    4.初始化sort_buffer,(由于用rowid排序)只有这个R字段与默认rowid字段。
    5.从临时表中取出R值与rowid,存入sort_buffer。(这个过程设计内存表的全表扫描会更加扫描行数。)
    6.sort_buffer根据R值排序。
    7.排序后取前三个结果rowid,到内存表取W字段返回给客户端。

小结:order by rand()使用了内存临时表,内存临时表排序的时候使用了rowid排序。

磁盘临时表
tmp_table_size这个参数限制了内存临时表的大小。默认值是16M,如果临时表的大小超过了tmp_table_size这个值。则内存临时表会转为磁盘临时表

磁盘临时表默认引擎使用innodb。由internal_tmp_disk_storage_engine控制的。

为了复现这个过程,把tmp_table_size=1024 sort_buffer_size=32768

max_length_for_sort_data=16
set tmp_table_size=1024;
set sort_buffer_size=32768;
set max_length_for_sort_data=16;
/* 打开 optimizer_trace,只对本线程有效 */
SET optimizer_trace=‘enabled=on’;

/* 执行语句 */
select word from words order by rand() limit 3;

/* 查看 OPTIMIZER_TRACE 输出 */
SELECT * FROM information_schema.OPTIMIZER_TRACE\G

查看optimizer_trace的结果。

number_of_tmp_files为0,不需要临时文件。
mysql5.6后引入了优先队列排序算法(大小根堆算法,不需要将所有的数据进行排序。)
select city,name,age from t where city=‘杭州’ order by name limit 1000 ;
之前我们只有三条记录,需要维护堆的大小只有3行。
但是现在我们将记录行扩展到了1000行,超过了设置的sort_buffer_size,只能选用归并排序。

小结:order by rand()不管用什么临时表,计算过程都比较复杂。需要扫描大量的行,且排序过程消耗大量的资源。

随机排序方法
随机算法1:
select max(id),min(id) into @M,@N from t;
set @X=floor((@M-@N+1)*rand()+@N);
select * from t where id >=@X limit 1;
1.获取这个表主键id的最大值M与最小值N
2.用随机函数生成一个M~N之间的数X
3.取不小于X的第一个ID的行。
缺点ID如果不连续,则M~N之前的空洞会影响其他行的概率。

随机算法2

select count(*) into @C from t;
set @Y = floor(@C * rand())//取整数部分
set @sql=concat("select * from t limit ", @Y, “,1”);
prepare stmt from @sql;
execute stmt;
deallocate prepare stmt;
1.取整个表的行数C。
2.用随机函数取得1~C之前的随机值
3.再用limit Y,1取得一行
mysql处理limit Y,1的做法是按顺序读入,丢弃前Y个,然后把下个作为结果返回。扫描行数会加上Y。 扫描行数增加了,但是解决了概率平均的问题。

这篇关于如何正确地显示随机消息?读后总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1128113

相关文章

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

C#实现SHP文件读取与地图显示的完整教程

《C#实现SHP文件读取与地图显示的完整教程》在地理信息系统(GIS)开发中,SHP文件是一种常见的矢量数据格式,本文将详细介绍如何使用C#读取SHP文件并实现地图显示功能,包括坐标转换、图形渲染、平... 目录概述功能特点核心代码解析1. 文件读取与初始化2. 坐标转换3. 图形绘制4. 地图交互功能缩放

Java 中的 equals 和 hashCode 方法关系与正确重写实践案例

《Java中的equals和hashCode方法关系与正确重写实践案例》在Java中,equals和hashCode方法是Object类的核心方法,广泛用于对象比较和哈希集合(如HashMa... 目录一、背景与需求分析1.1 equals 和 hashCode 的背景1.2 需求分析1.3 技术挑战1.4

如何正确识别一台POE交换机的好坏? 选购可靠的POE交换机注意事项

《如何正确识别一台POE交换机的好坏?选购可靠的POE交换机注意事项》POE技术已经历多年发展,广泛应用于安防监控和无线覆盖等领域,需求量大,但质量参差不齐,市场上POE交换机的品牌繁多,如何正确识... 目录生产标识1. 必须包含的信息2. 劣质设备的常见问题供电标准1. 正规的 POE 标准2. 劣质设

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

Java中如何正确的停掉线程

《Java中如何正确的停掉线程》Java通过interrupt()通知线程停止而非强制,确保线程自主处理中断,避免数据损坏,线程池的shutdown()等待任务完成,shutdownNow()强制中断... 目录为什么不强制停止为什么 Java 不提供强制停止线程的能力呢?如何用interrupt停止线程s

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

聊聊springboot中如何自定义消息转换器

《聊聊springboot中如何自定义消息转换器》SpringBoot通过HttpMessageConverter处理HTTP数据转换,支持多种媒体类型,接下来通过本文给大家介绍springboot中... 目录核心接口springboot默认提供的转换器如何自定义消息转换器Spring Boot 中的消息