• 【MySQL】06-排序


    全字段排序

    先把所有符合条件的行(和列)读到内存中,然后对相应字段进行快排

    外部排序

    内存中放不下全部的数据时进行,将一部分结果存入到文件中(磁盘中)

    rowid排序

    当一行中字段过多时,把待排序字段和rowID读入内存中,排序后,按照id再读一遍数据库。(读两遍,第一遍取排序字段,第二遍取select的字段)

    随机消息

    例如随机展示三个单词

    select word from words order by rand() limit 3;
    

    内存临时表

    这条语句的执行流程是这样的:

    1. 创建一个临时表。这个临时表使用的是memory引擎,表里有两个字段,第一个字段是double类型,为了后面描述方便,记为字段R,第二个字段是varchar(64)类型,记为字段W。并且,这个表没有建索引。
    2. 从words表中,按主键顺序取出所有的word值。对于每一个word值,调用rand()函数生成一个大于0小于1的随机小数,并把这个随机小数和word分别存入临时表的R和W字段中,到此,扫描行数是10000。
    3. 现在临时表有10000行数据了,接下来你要在这个没有索引的内存临时表上,按照字段R排序。
    4. 初始化 sort_buffer。sort_buffer中有两个字段,一个是double类型,另一个是整型。
    5. 从内存临时表中一行一行地取出R值和位置信息(建临时表时生成的rowid),分别存入sort_buffer中的两个字段里。这个过程要对内存临时表做全表扫描,此时扫描行数增加10000,变成了20000。
    6. 在sort_buffer中根据R的值进行排序。注意,这个过程没有涉及到表操作,所以不会增加扫描行数。
    7. 排序完成后,取出前三个结果的位置信息,依次到内存临时表中取出word值,返回给客户端。这个过程中,访问了表的三行数据,总扫描行数变成了20003。

    磁盘临时表

    如果临时表大小超过了tmp_table_size,那么内存临时表就会转成磁盘临时表。磁盘临时表使用的引擎默认是InnoDB。

    执行这条语句时,InnoDB会采用优先队列排序算法。(只取最小的三个,对剩余的不进行排序)

    当堆内存存不下所有的需求时,会采用快排+归并。

    优解

    无论用上述那种方法,都需要扫至少一遍全表。更优的解法如下:

    • 算法一

      1. 取得这个表的主键id的最大值M和最小值N;
      2. 用随机函数生成一个最大值到最小值之间的数 X = (M-N)*rand() + N;
      3. 取不小于X的第一个ID的行。

      但是缺点是伪随机,中间取得的概率大于两边的。(由其当主键不均匀时)

    • 算法二

      1. 取得整个表的行数,并记为C。
      2. 取得 Y = floor(C * rand())。 floor函数在这里的作用,就是取整数部分。
      3. 再用limit Y,1 取得一行。
  • 相关阅读:
    【转】JMeter学习(十六)JMeter函数学习
    【转】JMeter学习(十三)分布式部署
    【转】JMeter学习(十二)目录介绍
    【转】JMeter学习(十一)WebSerivice测试计划
    【转】JMeter学习参数化User Defined Variables与User Parameters
    JMeter学习(九)FTP测试计划
    【转】JMeter学习(八)JDBC测试计划-连接Oracle
    【转】JMeter学习(七)聚合报告之 90% Line 正确理解
    【转】JMeter学习(六)集合点
    springboot整合mybatisplus
  • 原文地址:https://www.cnblogs.com/Ryan16231112/p/13305817.html
Copyright © 2020-2023  润新知