写优雅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记录表就可以,但是并不能拿到预期的结果,因为<>强分组后的每个组结果是不进行排序的>强,而且马克斯拿到的最高分数肯定是对应的该分组下最高分数,但是其它记录可能就不是最高分数对应的那条记录。所以子查询非常有必要,<强>它能够对原始的数据首先进行排序>强,分数最高的那条就是第一条对应的第一条记录。
李>看一下代码和执行结果与带有子查询的进行比较,就能理解我上面说的一段话: