当前位置: 首页 > 网络应用技术

MySQL的订单如何执行?

时间:2023-03-07 12:19:45 网络应用技术

  注意:[]该系列是关于MySQL容易忽略的一些知识点。通过审查和补充,您还可以根据审查和补充来更系统地学习MySQL,以便更轻松地工作。

  在开发过程中,需要根据指定字段进行分类以显示结果。

  以先前的订单表为例,假设查询“张圣”的所有订单,并为订单价格排序以返回前1,000个订单号和价格。

  此顺序表测试的结构是这样:

  用户表数据:

  上方订单表的UID与用户表的ID关联。

  SQL语句可以像这样写:

  上面的SQL语句看起来很清楚,但是其执行过程是否理解?让我们了解该语句如何执行以及哪些参数会影响执行。

  为避免完整的表扫描,我们需要在UID字段上添加索引。

  将UID字段添加到索引后,我们使用命令来查看此语句的执行。

  额外字段中的“使用filesort”意味着需要对其进行排序。MySQL将为每个线程分配一个内存以进行排序,称为sort_buffer。

  为了解释此SQL查询语句的执行过程,让我们看一下UID索引的示意图。如下所示:

  通常,此陈述的执行过程如下:

  “排序OID”的动作可以在内存或外部排序中完成,这取决于存储器和参数sort_buffer_size分类所需的。

  sort_buffer_size是sort_buffer的mySQL的大小。如果要排序的数据量小于sort_buffer_size,则排序在内存中完成。用于协助分类临时文件。

  您可以使用下面描述的方法来确定是否使用临时文件。

  通过查看结果来确认此方法,您可以查看是否使用临时文件。

  表示分类过程中使用的临时文件数量。您必须很奇怪。我在当前测试中需要0个文件,表明分类可以直接在内存中完成。如果是n,则意味着当无法存储内部存储时,必须使用外部排序。通常使用外部排序算法。可以简要理解,

  注意:如果超过需要排序的数据量,则为0,这意味着可以直接在内存中完成排序。

  接下来,我将解释上图中其他两个值的含义。

  我们的示例表中有99972记录符合UID = 1,并检查了= 99972,表明参与线的数量为99972行。

  sort_mode是额外的_ fields。

  1. MySQL 4.1之前的相应“原始分类模式”。它显示排序缓冲元组包含排序键和原始表?的ID。分类后,需要将??ID制成板球。该算法也称为原始FileSort算法(返回排序算法);2.对应于相应的OneIT是MySQL 4.1之后引入的“修改分类模式”。排序缓冲区元组包含排序键值和查询所需的列。排序后,数据直接从缓冲元组中获取。这是MySQL 5.7.3.3.3.3.的进一步优化的“包装数据排序模式”。这与上层类型的形式相似,但是其他列(这样)由于VARCHAR类型)紧紧地包装在?中,并且?不是固定长度的编码。

  同时,上一个查询语句的返回结果选择 @b- @a为99973。

  那么为什么上面的99972不呢?

  在这里应该注意的是,为了避免干扰,您可以将internal_tmp_disk_storage_engine设置为myisam。待使用,并且Internet_tmp_disk_storage_engine的默认值是Innodb。如果使用InnoDB引擎,则在从临时表中取出数据时,Innodb_rows_read的值将添加1。

  上面的算法仅读取原始表的数据,其余操作是在sort_buffer和临时文件中执行的。但是,如果有很多字段要返回,则此算法存在问题,那么有太多字段可容纳很多字段。放置在sort_buffer中,以便可以同时放置在内存中的行数很小。这将是不好的。因此,如果单行很大,则此方法不够有效。

  如果MySQL想到排序的顺序太多,该怎么办?

  让我们修改一个参数以使MySQL采用另一种算法。

  max_length_for_sort_data是一个在mySQL中专门控制的参数。这意味着,如果单行的长度超过此值,mySQL会认为单行太大,您需要更改算法。

  OID和价格的两个字段的总长度为28。我将max_length_for_sort_data设置为16。让我们看看哪些更改已更改计算过程。

  新算法放置在sort_buffer的字段中,仅列(即价格字段)和要排序的主要密钥ID。

  但是目前,排序的结果是因为价格字段的价值丢失了,无法直接返回。整个执行过程如下所示:

  与完整的字段排序流程图相比,RowID对访问测试的主要键索引进行了更多分类,即步骤7。

  注意:最终的“结果集”只是一个逻辑概念。实际上,MySQL Server按顺序从Sort_buffer中取出ID,然后在原始表处找到OID和价格的两个字段的结果。存款存储的结果直接返回给客户端。

  那么此时将执行什么结果?

  首先,图中的usked_rows的值是99972,这表明用于排序的数据为99972行。因为除了此时的分类过程之外,分类过程完成后,原始表的值应根据id.ok获取)。

  从Optimizer_Trace的结果来看,您还可以看到另一个信息已更改。

  如果MySQL真的担心排序排序太小,则会影响分类效率,然后将使用ROWID排序算法。这样,可以在分类过程中对其进行排序,但是您需要返回原始表以拾取数据。

  如果MySQL认为内存足够大,则将优先考虑整个字段排序,并且所需字段的需求将放置在sort_buffer中,以便在排序之后,查询结果将直接从内存中返回,而且无需返回原始表即可拾取数据。

  这也反映了MySQL的设计思想:

  对于InnoDB表,ROWID排序将需要返回表才能引起更多的磁盘读数,因此不会首选。

  MySQL是一个相对较高的成本操作。所有需要排序操作都可以按订单?如果您可以在不进行排序的情况下获得正确的结果,那么系统的消耗将少得多,并且句子的执行时间将变得更短。,并非所有按语句订单都需要对操作进行排序。从上述分析的执行过程中,我们可以看到MySQL需要生成临时表并在临时表上进行排序操作的原因。

  如果您可以保证从UID的索引中获取的线,那么根据价格上涨的排序是很自然的,您不再能对您进行排序吗?

  因此,我们可以在此公民表上创建UID和价格的合并索引。相应的SQL语句是:

  与UID索引相反,让我们看一下该索引的示意图。

  在此索引中,我们仍然可以使用树搜索来定位满足UID = 1的第一个记录,并确保其他保证。接下来,在订单1中的“下一个记录”过程中。价格的价值必须有序。

  这样,整个查询过程的过程就变成了:

  此查询过程不需要临时表或排序。下一步,我们使用结果来确认。

  从图可以看出,在额外字段中没有使用filesort,也就是说,无需对其进行排序。而且,(uid,price)组合索引本身是有序的,此查询无需读取所有99972行。只要您找到符合条件的前1,000条记录,就可以退出。换句话说,在我们的示例中,我们只需要扫描1,000次。

  再次审查。

  额外字段中添加了“使用索引”,这意味着使用盖子索引,并且性能将更快。

  当然,这并不是说要涵盖每个查询的索引,声明中涉及的字段必须共同索引。毕竟,该指数仍然具有成本效益。这是需要权衡的决定。

  结尾

  如果您有任何疑问,请在下面留言。

  或注意我的公共帐户“”(),输入”。寻求进一步的帮助。

  原始:https://juejin.cn/post/71019497807934221