写优雅SQL原生语句的方法

  介绍

写优雅SQL原生语句的方法?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让我们一起来看看吧!

前言:

上一篇讲Mysql基本架构时,以“SQL查询语句在Mysql架构中具体是怎么执行的“   进行了全面的讲解。知道了sql查询语句在MySql架构中的具体执行流程,但是为了能够更好更快的写sql语出句,我觉得非常有必要知道sql语句中各子句的执行顺序。看过上一篇文章的小伙伴应该都知道,sql语句最后各子句的执行应该是在执行器中完成的,存储引擎对执行器提供的数据读写接口。现在开始我们的学习

语句中各子句完整执行顺序概括(按照顺序号执行)

<李>

从(注:这里也包括从中的子语句)

<李>

<李>

<李>

<李>

集团(开始使用选择中的别名,后面的语句中都可以使用)

<李>

avg, ....总和等聚合函数

<李>

<李>

选择<李>

<李>

,

<李>

限制

每个子句执行顺序分析

所有的查询语句都是从从开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入。

1。从

形式是一次查询语句的开端。

<李>

如果是一张表,会直接操作这张表;

<李>

如果这个从后面是一个子查询,会先执行子查询中的内容,子查询的结果也就是第一个虚拟表T1。(注意:子查询中的执行流程也是按照本篇文章讲的顺序哦)。

<李>

如果需要关联表,使用加入,请看2、3

2。加入

如果从后面是多张表,加入关联,会首先对前两个表执行一个笛卡尔乘积,这时候就会生成第一个虚拟表T1(注意:这里会选择相对小的表作为基础表),

3。在
,

对虚表T1进行上筛选,只有那些符合的行才会被记录在虚表T2中。(注意,这里的这里如果还有第三个表与之关联,会用T2与第三个表进行笛卡尔乘积生产T3表,继续重复3。李>

因为order by返回值是游标,那么使用order by子句查询不能应用于表表达式。

<李>

按排序是很需要成本的,除非你必须要排的序,否则最好不要指定顺序,

<李>

命令的两个参数,asc(升序排列),desc(降序排列)

11。限制

取出指定行的记录,产生虚拟表T9,并将结果返回。

限制后面的参数可以是一个限制,也可以是限制mn,表示从第m条到第n条数据。

(注意:很多开发人员喜欢使用该语句来解决分页问题。对于小数据,使用限制子句没有任何问题,当数据量非常大的时候,使用限制n, m是非常低效的。因为限制的机制是每次都是从头开始扫描,如果需要从第60万行开始,读取3条数据,就需要先扫描定位到60万行,然后再进行读取,而扫描的过程是一个非常低效的过程,所以,对于大数据处理时,是非常有必要在应用层建立一定的缓存机制)

开发某需求写的一段sql

选择“userspk”。《阿凡达》作为“user_avatar”,   ‘一个’。‘user_id’,   ‘一个’。‘answer_record’,   马克斯(“分数”)的分数从(select * from pkrecord订单通过分数desc)作为一个   内连接的userspk userspk的alt="写优雅SQL原生语句的方法">

<李>

先简要说一下我要查询的内容:

想要查询pk记录表中分数最高的9个用户记录和他们的头像。

<李>

通过这段SQL实际想一遍SQL各字句的执行顺序

pk记录表的数据结构设计,每个用户每天每个馆下可能会有多条记录,所以需要进行分组,并且<强>查询结果只想拿到每个分组内最高的那条记录

这段SQL的一些说明:

<李>

可能有些同学会认为子查询没有必要的   直接查询pk记录表就可以,但是并不能拿到预期的结果,因为<>强分组后的每个组结果是不进行排序的强,而且马克斯拿到的最高分数肯定是对应的该分组下最高分数,但是其它记录可能就不是最高分数对应的那条记录。所以子查询非常有必要,<强>它能够对原始的数据首先进行排序强,分数最高的那条就是第一条对应的第一条记录。

看一下代码和执行结果与带有子查询的进行比较,就能理解我上面说的一段话:

写优雅SQL原生语句的方法