sql查询语句并不是最先执行SELECT

很多的SQL查询语句都是以SELECT关键字开始的,所以我们很容易会以为SQL查询语句就是最先执行的SELECT。不过,当我尝试跟别人解释什么是窗口函数的时候,针对是否可以对窗口函数返回的结果进行过滤这个问题,最终得出的结论是窗口函数的执行必须在WHERE子句和GROUP BY子句之后,所以不能对窗口函数返回的结果进行再次过滤。于是我又想到了另一个问题:SQL查询的执行顺序究竟是怎样的?

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

SQL查询语句的执行顺序

于是我研究了一下,发现在SQL语句的执行顺序中,SELECT并不是最先执行的,而是在第五个。

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

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

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

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

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

但数据库引擎并不一定严格按照这个顺序执行SQL查询,因为它们为了更快地执行查询,会对执行顺序做出一些优化。也就是说,当涉及查询性能或者与索引有关的东西时,这张图就不适用了。

混合因素:列别名

有很多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 = ‘tommy‘

如果只需要找出名字叫tommy的猫,那就没必要对两张表的所有数据执行左连接,而是应该在连接之前先进行过滤,这样查询会快得多。而且对于这个查询来说,先执行过滤并不会改变查询结果。因此在这里数据库引擎会根据执行效率最优对执行顺序进行优化,生成相对应的执行计划方案。

"不要眼眶一红,就觉得人间不值得。"

原文地址:https://www.cnblogs.com/yanggb/p/12204499.html

时间: 2024-08-28 09:19:47

sql查询语句并不是最先执行SELECT的相关文章

Hibernate 关于执行sql查询语句(转)

原文  http://www.yshjava.cn/post/543.html 主题 SQLHibernate Hibernate对原生SQL查询的支持和控制是通过SQLQuery接口实现的.通过Session接口,我们能够很方便的创建一个SQLQuery(SQLQuery是一个接口,在Hibernate4.2.2之前,默认返回的是SQLQuery的实现类--SQLQueryImpl对象,在下文中出现的SQLQuery如非注明,都是指该子类)对象来进行原生SQL查询: session.creat

EF5中 执行 sql语句使用Database.ExecuteSqlCommand 返回影响的行数 ; EF5执行sql查询语句 Database.SqlQuery 带返回值

一: 执行sql语句,返回受影响的行数 在mysql里面,如果没有影响,那么返回行数为  -1 ,sqlserver 里面  还没有测试过 using (var ctx = new MyDbContext()) { ctx.Database.ExecuteSqlCommand("UPDATE Person SET Name = 'Michael' WHERE PersonID = 1"); } 二 : Database.SqlQuery<T>   EF5执行sql查询语句

浅谈SQL优化入门:1、SQL查询语句的执行顺序

1.SQL查询语句的执行顺序 (7) SELECT (8) DISTINCT <select_list> (1) FROM <left_table> (3) <join_type> JOIN <right_table> (2) ON <join_condition> (4) WHERE <where_condition> (5) GROUP BY <group_by_list> (6) HAVING <having_

一条SQL查询语句是如何执行的

一条SQL查询语句是如何执行的 下面是MySql的基本架构示意图,从图中可以清楚地看到SQL语句在MySQL的各个功能模块中的执行过程. 大体来讲,MySQL可以分为Server层和存储引擎层两部分. Server层 Server层包括连接器.查询缓存.分析器.优化器.执行器等,涵盖了MySql的大多数核心服务功能以及所有的内置函数,所有跨存储引擎的功能都在这一层实现,比如存储过程.触发器.视图等. 存储引擎层 而存储引擎层负责数据的存储与提取.其架构模式是插件式的,支持InnoDB.MyISA

将Sql查询语句获取的数据插入到List列表里面

Sql查询语句获取的数据是分格式的,我们还用SqlDataReader来做,然后用IDataReader来接收读取,以下是代码: //我想查询一个用户表的信息,该用户有姓名,密码,信息三列 //1.定义一个用户类型的List数组,userInfo类的代码在下方 List<userInfo> userInfo = new List<userInfo>(); //2.我们要读取查询语句的数据,并且保存了.这里我们将使用IDataReader语句 //数据库类的实例,类的代码在下方 DB

如何编写高效的SQL查询语句

概述 如何编写性能比较高的SQL查询语句呢?两个方法:创建合理的索引:书写高效的SQL语句 索引的基本原理 索引分为聚集索引和非聚集索引.一个表只能创建一个聚集索引和N个非聚集索引,这句话的由来主要是由于索引的原理决定的. 数据库中的一张表不论你创建不创建索引,或者,不论你创建那种类型的索引,其在硬盘上的存储是一样的,那么,创建索引和不创建索引,或者,创建聚集索引和非聚集索引的区别在什么地方呢? 其区别是表内数据在内存的存在形式.对于没有创建索引的表,其加载到内存里时,就只有数据块:对于有聚集索

Java连接MySQL数据库实现用户名密码的验证方法 Java语句中sql查询语句&#39;&#39; &quot;&quot;作用

//方法一,可以验证登录,但方法不实用.package com.swift; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; public class Logi

(转)经典SQL查询语句大全

一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- 创建 备份数据的 device USE master EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat' --- 开始 备份 BACKUP DATABASE pubs TO testBack 4.说明:创建

sql查询语句优化

http://www.cnblogs.com/dubing/archive/2011/12/09/2278090.html 最近公司来一个非常虎的dba  10几年的经验 这里就称之为蔡老师吧 在征得我们蔡老同意的前提下  我们来分享一下蔡老给我们带来的宝贵财富 欢迎其他的dba来拍砖  目录 1.什么是执行计划?执行计划是依赖于什么信息.2. 统一SQL语句的写法减少解析开销3. 减少SQL语句的嵌套4. 使用“临时表”暂存中间结果5. OLTP系统SQL语句必须采用绑定变量6. 倾斜字段的绑