首页 > 数据库 >Mysql中的双路排序和单路排序

Mysql中的双路排序和单路排序

时间:2024-05-08 18:55:06浏览次数:12  
标签:双路 price 索引 单路 排序 id

在Mysql中使用orderby进行排序的时候,是可以使用到索引排序的,但是需要添加一些限制条件,例如:
select * from t_user where name='张三' order by name;使用这种方式就可以使用到索引,同时使用limit也是可以使用到索引的
select * from t_user order by name;通过这种方式不会使用到索引

什么时候出现索引排序,什么时候出现文件排序:

  • 索引排序:当Mysql能够使用索引来执行查询并且可以利用索引中的信息来实现排序的时候,叫索引排序
  • 文件排序:当Mysql不能通过索引中的数据实现排序,叫文件排序

Mysql中的索引排序的流程:
select id,price from likes where price=199 order by price; sql 1
select id,name,price from likes where price =199 order by price; sql 2
这里存在两种情况,一种是存在覆盖索引的情况,如果存在覆盖索引(sql 1)就会通过索引进行排序之后直接返回,第二种情况是需要进行回表查询的情况(sql 2),需要先通过索引进行排序,排序完成之后通过id回表查询我们需要的数据。
 
 

我们要尽量使用索引排序,如果没有使用索引排序,mysql就是使用文件排序(filesort)
文件排序有两种:

  • 双路排序(回表排序模式):在执行的时候,会先根据条件将排序字段和主键id(定位行数据的字段)进行取出,然后放到sortbuff中(执行排序时分配的内存)进行排序,在排序完成之后需要通过主键id回表查询出其他我们需要的数据。
  • 单路排序:在执行的时候,会将我们需要的数据都加载到sortbuff中进行排序,排序完成之后,直接将内存中的数据直接返回,不需要在进行回表查询。

这里举一个例子:
select id,name,price from likes order by price;,我们在price列中创建了索引,但是因为没有条件限制,我们还是会走filesort的

当使用单路排序的时候:
这里我们需要的数据是 id、name、price,所以他就会将对应的这三列的数据放到sortbuff中,通过对price字段进行排序,排序完成之后,直接就将数据进行返回了。

当使用双路排序的时候:
尽管我们需要id、name、price,在排序的时候,也只会将id(定位行数据的字段,建立聚簇索引的字段),price字段(通过该字段进行排序)加载到sortbuff中,通过对price字段进行排序,排序完成之后,会将排序结果集中的id进行回表查询(因为我们还需要name字段),查询出我们需要的数据,在进行返回

双路排序和单路排序的优缺点:

  • 双路排序:因为双路排序需要继续两次访问数据,所以效率较慢
  • 单路排序:单路排序只需要访问数据一次就行了,所以效率较高,但是因为单路排序是将我们需要的数据都存储在内存中,所以可能会占用更多的内存。

注意下:当sortbuff不足的时候,mysql会使用磁盘用来辅助排序,这种情况在双路排序和单路排序中都可能发生,那是不是单路排序出现这种情况的次数会更多呢?其实不然,单路排序通常不会出现这种情况,为什么呢,这需要了解什么时候使用单路排序,什么时候使用双路排序。

双路排序和单路排序如何选择的:

在排序的时候,会首先判断是索引排序还是文件排序,如果是索引排序,就通过索引排序进行,如果是文件排序,首先需要判断我们需要的字段(例如上述例子中的id、name、price)的总大小是否超过max_length_for_srot_data,如果超过了就会使用双路排序,如果没有超过就会使用单路排序。

标签:双路,price,索引,单路,排序,id
From: https://www.cnblogs.com/just1t/p/18180663

相关文章

  • 归并排序
    归并排序模板constintN=1e6+10;inta[N],tmp[N];//定义一个缓存数值voidmerge_sort(intq[],intl,intr){if(l>=r)return;intmid=l+r>>1;merge_sort(q,l,mid),merge_sort(q,mid+1,r);intk=0,i=l,j=mid+1;......
  • 快速排序
    快速排序快排模板(以j为分界)快排属于分治算法,分治算法都有三步:1.分成子问题2.递归处理子问题3.子问题合并voidquick_sort(intq[],intl,intr){//递归的终止情况if(l>=r)return;//第一步:分成子问题 inti=l-1,j=r+1,x=q[1+r>>......
  • dataframe的构造,取值,赋值,移动,交集,并集,排序,打印,转List,导出csv
    一、构造  da=pd.read_csv(filepath_or_buffer='data.csv',sep='\t')  print(da)  datas=pd.DataFrame(da)2、直接赋值df=pd.DataFrame([[1.4,np.nan],[7,-4],[np.nan,np.nan],[0.75,-1.3]],index=[1,2,3,4],         columns=[......
  • 选择排序
    //选择排序从序列中找到一个最小值元素,把最小值元素放在整个序列的首部,重复n轮,直到整个序列有序voidSelectSort(intbuf[10],intsize){ intmin=0;//记录最小值元素的下标 inttemp=0;//备份最小值元素的值 //需要比较n轮,每轮找到序列中的最小值元素 for(intn......
  • 二分法、冒泡排序
    【一】二分法二分法查找,也称为折半法,是一种在有序数组中查找特定元素的搜索算法思路:首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤的操作。如......
  • 常见的排序算法——归并排序(二)
    本文记述了自底向上归并排序的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。◆思想使用自底向上的递推思想进行排序。从大小为1的子范围开始两两归并,得到小规模排序的结果。逐步将子范围的大小翻倍并继续两两归并,直到整个数组范围都已被归并,即得......
  • 01选择排序
     1.选择排序含义每次选择最小的,放到左侧。持续进行。 2.示例代码:defselectionSort(arr):foriinrange(len(arr)-1):#记录最小数的索引minIndex=iforjinrange(i+1,len(arr)):ifarr[j]<arr[minIndex]:......
  • 插入排序
    插入排序简单来说假设数组第一个元素为一个有序序列然后将后面的无序序列依次与第一个元素比较更具大小决定待插入元素插入的位置。、、、//插入排序是吧无序序列中的元素依次插入到有序序列中,一般是从有序序列的尾部开始比较voidInsertSort(intbuf[10],intbufsize){......
  • 冒泡排序法(从左到右升序 )
    /**@filename: main.c@brief冒泡排序@[email protected]@date2024/05/[email protected]:版本@property:属性介绍@note补充注意说明CopyRight(c)[email protected]*///冒泡排序,指的是元素两两之间进行比较交......
  • 冒泡排序
    冒泡排序冒泡排序也被称为起泡排序,该排序算法的原理就是经过一系列的交换实现的,也就是用第一个元素和第二个元素进行比较,如果第一个元素的值大于第二个元素则两者位置互换,否则不交换。然后第二个元素和第三个元素比较.......最后序列中最大的元素被交换到了序列的尾部,这样就完成......