MySQL排序原理及实例分析
2023-11-18 12:46:32
前言 排序是数据库的一个基本功能,MySQL也不例外,用户可以通过语句顺序来实现指定结果集的排序。事实上,他们是由报表不仅秩序,通过报表,不同的报表组,而且使用排序。本文将介绍如何使用SQL简单索引避免订货成本,然后介绍了MySQL的实现原理,介绍了内部排序和排序相关参数,最后给出了奇怪的一些例子,排序一致性,解释现象的本质原因。 1。排序优化和索引使用 为了优化SQL语句的排序性能,最好的办法是避免排序,它是利用指标合理的好方法。因为指数本身是有序的,如果我们建立一个合适的指标对需要排序的字段,我们可以跳过排序过程提高SQL查询速度。下面,我用一些典型的SQL来说明SQL可以使用索引来减少排序和SQL不是。假设T1表有一个指数(key_part1 KEY1,key_part2),key2(key2) A.可以使用索引来避免某种SQL SELECT * FROM的key_part1 T1秩序,key_part2; SELECT * FROM T1 WHERE key_part1 = constant ORDER BY key_part2; SELECT * FROM T1,key_part1 >的key_part1 ASC常数阶; SELECT * FROM T1,key_part1 = constant1和key_part2 > constant2顺序key_part2; 不能使用索引避免对SQL进行排序。 在多个索引中的排序字段,不能使用索引进行排序。 SELECT * FROM的key_part1,key_part2 T1,key2; 排序键序列和索引中的列顺序不一致,不能使用索引排序。 SELECT * FROM的key_part2 T1秩序,key_part1; 提升顺序不,不能使用索引排序。 SELECT * FROM的key_part1 DESC T1秩序,key_part2 ASC; / / key_part1是范围查询,和key_part2不能排序的索引 SELECT * FROM T1,key_part1 >定为key_part2; 2。排序算法实现 避免使用SQL不能排序的索引数据库,实现自身的排序功能来满足用户的需求,使用SQL程序会出现filesort,应该指出的是,filesort并不意味着文件实际上是排序,也有可能是内存排序,主要由sort_buffer_size参数确定结果集的大小。有3种方法来实现MySQL内部排名,包括定期整理、排序和优先级队列排序。它主要涉及3种排序算法:快速排序、归并排序和堆排序。假设表结构和sql语句如下所示: 创建表T1(ID int,COL1,COL2 varchar(64)varchar(64),(64),原col3 varchar); 选择COL1,COL2,col3从T1在col1 > 100阶的COL2; A.常规排序 (1)。记录表T1的条件 (2)。为每一个记录,记录的主要关键+排序关键字(ID,COL2)放入排序缓冲区 (3)如果排序缓冲器可以存储所有(ID,COL2)对符合要求的,将被排序;否则,如果排序缓冲区已满,将排序和凝固成临时文件。(排序算法快速排序算法) (4)如果在一个排序中生成一个临时文件,我们需要使用合并排序算法来确保临时文件中的记录是有序的。 (5)。循环执行上述过程,直到满足条件的所有记录都与排序有关。 (6)。扫描排序(ID,COL2),并利用ID返回寻找(col1,col2列选择,col3) (7)。将得到的结果集返回给用户。 从上面的过程中,无论是文件分类取决于是否排序缓冲区可以包含ID(COL2)对。这个缓冲区的大小是由sort_buffer_size参数控制。此外,一个订单需要两倍的IO,一个是钓鱼(ID,COL2),第二(col1,col2钓鱼,col3),因为结果集的排名是由COL2,所以ID是无序的。第二次,MySQL本身优化。首先,ID排序进入缓冲区前,和缓冲区的大小是由read_rnd_buffer_size控制参数。然后按顺序进行记录,并将随机IO转换为顺序IO。 B.优化排序 除了排序本身,定期整理要求两个额外的IO倍。优化排序方法比传统的排序IO减少二次。主要的区别是,排序缓冲区不(ID,COL2)(COL1,COL2,但是,col3)。由于排序缓冲区包含的所有字段的查询必需的,它可以在排序是没有两数据直接完成返回。这种方式的成本是排序缓冲大小相同(col1,col2可以存储少,col3)比ID和col2。如果排序缓冲区不够大,它可能会导致临时文件被写入,造成额外的IO。当然,MySQL提供的参数max_length_for_sort_data。只有当排序元组小于max_length_for_sort_data,我们可以利用的最优排序的方式,否则我们只能用传统的分类方式。 C.优先级队列排序 为了得到最终的排序结果,不管怎样,我们需要对所有满意的记录进行排序,以便返回。5.6版本在空间级别上按限制m和n语句进行了优化。一种新的排序方法——优先队列的方法,这是由堆排序实现。特征的限制只是解堆排序算法,这类问题,虽然仍需要所有参与排序,排序缓冲区空间的元素可以,但只有一个元组M + N M,N个小场景,基本上不是因为排序缓冲区因为不需要临时文件归并排序问题,升阶,大顶的反应器。最后一堆中的元素由最小的n个元素组成。对于下降顺序,使用小顶反应堆,最后堆中的元素构成最大n元素。 三.排序不一致 案例1 MySQL迁移后从5.5到5.6,发现重复的分页。 测试表和数据: 创建表T1(ID为主键,C1 int,C2 varchar(128)); 插入T1值(1,1,'a'); 插入T1值(2,2,'b'); 插入T1值(3,2,c); 插入T1值(4,2,会); 插入T1值(5,3,e); 插入T1值(6,4,F); 插入T1值(7,5,'克'); 假设每3页记录,第一页的限制条件的结果和第二页的限制、查询如下: 我们可以看到,在4号的记录出现在同一时间两个查询,这显然是不一样的预期,也在5.5版中没有这样的问题。造成这种现象的原因是5.6极限m,n语句使用一个优先队列和优先级队列使用堆,作为在上面的例子中,C1 ASC限制0, 3的前3个反应器的尺寸;极限3, 3前6堆的大小。因为C1有2记录,3,和堆排序是不稳定的。(对于相同的键值,它不能保证排序之前的排序与位置一致),导致分页的重复。为了避免这个问题,我们可以在排序中添加唯一的值,比如主键ID,这样id是唯一确保排序键值不同的: SELECT * FROM C1 T1,ID ASC的限制条件; SELECT * FROM C1 T1,ID ASC限制3; 案例2 除了不同的返回列之外,两个相似的查询语句是相同的,但是排序结果不一致。 测试表和数据: 创建表T2(ID为主键,地位int,C1,C2,C1 varchar(255)(255),255); 插入的T2值(7,1,'a',重复(A,255),重复(A,255)); 插入的T2值(6,2,B,重复(A,255),重复(A,255)); 插入的T2值(5,2、C、重复(A,255),重复(A,255)); 插入的T2值(4,2,'a',重复(A,255),重复(A,255)); 插入的T2值(3,3,B,重复(A,255),重复(A,255)); 插入的T2值(4,C,重复(A,255),重复(A,255)); 插入的T2值(1,5,'a',重复(A,255),重复(A,255)); 分别执行SQL语句: 选择身份,地位,C1,C2从T2力量指数(C1)其中C1 > = B。 选择ID,从T2力量指数状态(C1)其中C1 > = 'b'order的; 执行的结果如下: 看看这两个执行计划是否相同 为了说明这个问题,我在语句中添加了强制索引的提示,以确保C1列索引可以被接受。C1语句用于列索引id,然后返回返回的表。根据C1列值的大小,在C1索引中记录的相对位置如下所示: (C1,ID)=(B,6),(B,3),(5,C),(C,2),相应的状态值为2324。该数据由表状态排序,然后相对位置变化(6,2,B),(5,C),(3,C),(4,C),这是第二个查询返回结果,为什么第一个查询(6,2,B,5、()C)是为了更换这就是我提到的常规早、B.优化排序的红色部分,你能理解的原因。查询的第一列返回超过max_length_for_sort_data字节数,导致传统的顺序排序,在这种情况下,MySQL的rowid排序,随机IO,IO这样的回报是5,在第一,6和第二在后;使用查询优化的过程,没有过程二次排序的记录数据,保持相对位置,先声明,如果你想使用的优化排序,我们会得到max_length_for_sort_data设置,例如,2048。 以下是一点我的关于MySQL的领域知识(仪器、定位),希望对你有帮助 第一点是,有三个功能(秩序的领域,以指导,以定位) 原表: 用户通过身份 AAA AAA BBB BBB CCC认证 DDD DDD 噫噫 FFF FFF 以下是我执行死刑的结果: SELECT * FROM `的领域为用户`(考察,ID)ASC 用户通过身份 AAA AAA CCC认证 DDD DDD 噫噫 FFF FFF BBB BBB 根据研究结果,通过现场秩序的结果(2,3,5,4,1,6)显示为:134562 SELECT * FROM `的领域为用户`(考察,ID)描述 用户通过身份 BBB BBB AAA AAA CCC认证 DDD DDD 噫噫 FFF FFF 根据研究结果,通过现场秩序的结果(2,3,5,4,1,6)显示为:213456 SELECT * FROM `通过指导用户`阶('2,3,5,4,ID)ASC 用户通过身份 AAA AAA FFF FFF BBB BBB CCC认证 噫噫 DDD DDD 根据研究结果,通过教学秩序的结果(2,3,5,4,1,6)显示为:162354 SELECT * FROM `通过指导用户`阶('2,3,5,4,ID)描述 用户通过身份 DDD DDD 噫噫 CCC认证 BBB BBB AAA AAA FFF FFF 根据研究结果,通过教学秩序的结果(2,3,5,4,1,6)显示为:453216 SELECT * FROM `被定位为用户`(ID,'2,3,5,4 ASC的) 用户通过身份 AAA AAA FFF FFF BBB BBB CCC认证 噫噫 DDD DDD 根据这一结果,结果以定位(2,3,5,4,1,6)显示为:162354 SELECT * FROM `被定位为用户`(ID,'2,3,5,4 DESC) 用户通过身份 DDD DDD 噫噫 CCC认证 BBB BBB AAA AAA FFF FFF 根据这一结果,结果以定位(2,3,5,4,1,6)显示为:453216 如果我想在我的一次找到数据库(考察)和以其他身份,你必须先把他依次为(4532),然后从`通过仪器用户`秩序的选择*行('4,5,3,2,ID)、` DESC LIMIT从用户`订单或选择*(ID,找到'4,5,3,2)属性将得到你想要的结果。 用户通过身份 BBB BBB CCC认证 噫噫 DDD DDD AAA AAA FFF FFFtag:实例分析 排序 原理 电脑软件 mysql
相关内容