mysql随机数生原理(mysql实现原理和机制)

志在巅峰的攀登者,不会陶醉在沿途的某个脚印之中

1 前言

如下我这里有一张抽题记录表

mysql随机数生原理(mysql实现原理和机制)

执行时间 6.73秒,这个时间是绝对无法容忍的,你知道这个过程发生了什么吗???

2 MySql 的 rand 查询过程 内存临时表

select * from question_extracting order by rand() limit 4

上述这一句话先随机排序,再取前4条,它的执行过程如下:

  • 第一步 创建一个临时表,有两个字段,一个是double 类型使用A表示,另一个是 varchar(64) 类型 使用B表示,记为 字段 W,需要注意的是这个表没有建索引。
  • 第二步就是 从 上述 question_extracting 表中,按主键顺序取出所有的行(因为这里需要的是每行的所有数据),对于每一行数据,调用 rand() 函数生成一个大于 0 小于 1 的随机小数,并把这个随机小数和这一行数据 分别存入临时表的 A 和 B 字段中,需要扫描全表,如这里的 4974098 行。
  1. 第三步就是在临时表中按照字段 A 排序,初始化 sort_buffer,sort_buffer 中会放两个字段,一个是 double 类型,用来放临时表中的 A 字段,另一个是整型,用来放临时表中对应的数据的行号。
  2. 第四步就是在 sort_buffer 中根据 A 的值进行排序,排序完成后,取出前 4 个结果的位置信息,然后回到依次到内存临时表中取出 对就的行信息 值,返回给 客户端。

mysql随机数生原理(mysql实现原理和机制)

随机算法的正确姿势

mysql随机数生原理(mysql实现原理和机制)

你并没有看错,这就是正确的写法

select max(id),min(id) into @A,@B from question_extracting ;set @C= floor((@A-@B+1)*rand() + @B);select * from question_extracting where id >= @C limit 1;

可描述如下:

  • 第一步 取得这个表的主键 id 的最大值 M 和最小值 N,这个过程不需要扫描表
  • 第二步 用随机函数生成一个最大值到最小值之间的数 C = (A-B)*rand() + B;
  • 第三步 取不小于 C 的第一个 ID 的行

完毕

不局限于思维,不局限于语言限制,才是编程的最高境界。

推荐阅读:MySql 你真的会使用字符串索引吗?

(0)
小多多的头像小多多创始人

相关推荐

发表回复

登录后才能评论