热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

postgre查询表是否存在dapper_SQL查询语句总是先执行SELECT?你们都错了

点击蓝色“java版web项目”关注我哟加个“星标”,优质文章,第一时间送达上一篇:这300G的Java资料是我师傅当年给我的࿰

点击蓝色“java版web项目”关注我哟

加个“星标”,优质文章,第一时间送达

9d7f6987f65a3e1cdddc30e0c4fcf9b0.png

上一篇:这300G的Java资料是我师傅当年给我的,免费分享给大家

下一篇:这200G的Java实战资料是我师傅当年教我的第二招

作者 :Julia Evans 

译者 :无明

来源整理:高效开发运维

原文:http://suo.im/4wmt7

很多 SQL 查询都是以 SELECT 开始的。不过,最近我跟别人解释什么是窗口函数,我在网上搜索”是否可以对窗口函数返回的结果进行过滤“这个问题,得出的结论是”窗口函数必须在 WHERE 和 GROUP BY 之后,所以不能”。于是我又想到了另一个问题:SQL 查询的执行顺序是怎样的?

这个问题好像应该很好回答,毕竟自己已经写了上万个 SQL 查询了,有一些还很复杂。但事实是,我仍然很难确切地说出它的顺序是怎样的。

SQL 查询的执行顺序

于是我研究了一下,发现顺序大概是这样的。SELECT 并不是最先执行的,而是在第五个。

314c8c15e212b944aa426286aac62194.png

这张图回答了以下这些问题

这张图与 SQL 查询的语义有关,让你知道一个查询会返回什么,并回答了以下这些问题:

1.可以在 GRROUP BY 之后使用 WHERE 吗?(不行,WHERE 是在 GROUP BY 之前!)

2.可以对窗口函数返回的结果进行过滤吗?(不行,窗口函数是 SELECT 语句里,而 SELECT 是在 WHERE 和 GROUP BY 之后)

3.可以基于 GROUP BY 里的东西进行 ORDER BY 吗?(可以,ORDER BY 基本上是在最后执行的,所以可以基于任何东西进行 ORDER BY)

4.LIMIT 是在什么时候执行?(在最后!)

但数据库引擎并不一定严格按照这个顺序执行 SQL 查询,因为为了更快地执行查询,它们会做出一些优化,这些问题会在以后的文章中解释。

所以:

1.如果你想要知道一个查询语句是否合法,或者想要知道一个查询语句会返回什么,可以参考这张图;

2.在涉及查询性能或者与索引有关的东西时,这张图就不适用了。

混合因素:列别名

有很多 SQL 实现允许你使用这样的语法:

SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*)
FROM table 
GROUP BY full_name

从这个语句来看,好像 GROUP BY 是在 SELECT 之后执行的,因为它引用了 SELECT 中的一个别名。但实际上不一定要这样,数据库引擎可以把查询重写成这样:

SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*)
FROM table 
GROUP BY CONCAT(first_name, ' ', last_name)

这样 GROUP BY 仍然先执行。

数据库引擎还会做一系列检查,确保 SELECT 和 GROUP BY 中的东西是有效的,所以会在生成执行计划之前对查询做一次整体检查。

数据库可能不按顺序执行查询(优化)

在实际当中,数据库不一定会按照 JOIN、WHERE、GROUP BY 的顺序来执行查询,因为它们会进行一系列优化,把执行顺序打乱,从而让查询执行得更快,只要不改变查询结果。

这个查询说明了为什么需要以不同的顺序执行查询:

SELECT * FROM 
owners LEFT JOIN cats ON owners.id = cats.owner
WHERE cats.name = 'mr darcy'

如果只需要找出名字叫“mr darcy”的猫,那就没必要对两张表的所有数据执行左连接,在连接之前先进行过滤,这样查询会快得多,而且对于这个查询来说,先执行过滤并不会改变查询结果。

数据库引擎还会做出其他很多优化,按照不同的顺序执行查询,不过我并不是这方面的专家,所以这里就不多说了。

LINQ 的查询以 FROM 开头

LINQ(C# 和 VB.NET 中的查询语法)是按照 FROM...WHERE...SELECT 的顺序来的。这里有一个 LINQ 查询例子:

var teenAgerStudent = from s in studentList
                      where s.Age > 12 && s.Age <20 
                      select s;

pandas 中的查询也基本上是这样的&#xff0c;不过你不一定要按照这个顺序。我通常会像下面这样写 pandas 代码&#xff1a;

df &#61; thing1.join(thing2) # JOIN
df &#61; df[df.created_at > 1000] # WHERE
df &#61; df.groupby(&#39;something&#39;, num_yes &#61; (&#39;yes&#39;, &#39;sum&#39;)) # GROUP BY
df &#61; df[df.num_yes > 2] # HAVING, 对 GROUP BY 结果进行过滤
df &#61; df[[&#39;num_yes&#39;, &#39;something1&#39;, &#39;something&#39;]] # SELECT, 选择要显示的列
df.sort_values(&#39;sometthing&#39;, ascending&#61;True)[:30] # ORDER BY 和 LIMIT
df[:30]

这样写并不是因为 pandas 规定了这些规则&#xff0c;而是按照 JOIN/WHERE/GROUP BY/HAVING 这样的顺序来写代码会更有意义些。不过我经常会先写 WHERE 来改进性能&#xff0c;而且我想大多数数据库引擎也会这么做。

R 语言里的 dplyr 也允许开发人员使用不同的语法编写 SQL 查询语句&#xff0c;用来查询 Postgre、MySQL 和 SQLite。

说句题外话&#xff0c;想和老赵聊聊面试相关的经验、技术可以加我微信&#xff0c;但是坑位有限哦

28049fc9c6067e03af68b1da396204af.png

猜你喜欢

1、阿里规定超过三张表禁止join&#xff0c;这是为什么&#xff1f;

2、Logback 配置文件这么写&#xff0c;日志 TPS 提高 10 倍

3、9个爱不释手的JSON工具

4、小王&#xff0c;当Redis内存被打满了&#xff0c;会发生什么&#xff1f;

5、SpringBoot这样优化&#xff0c;让你的项目飞起来&#xff01;

6、细说 Java 主流日志工具库

7、后端开发都应该掌握的Redis基础

8、我为什么不再推荐 RxJava

强烈推荐一位大佬的公众号

c8851451ecf980b463eafb3510ca13b2.png

好文章&#xff0c;我在看❤️




推荐阅读
author-avatar
手机用户2502920645
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有