你真的知道SQL是怎么执行的吗

393 阅读5分钟

sql是什么

结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。

CRUD BOY? crude boy 对待亲爱的代码我们可不能粗鲁的crude!

sql有什么

  • 1、数据查询语言(DQL: Data Query Language):其语句,也称为“数据检索语句”,用以从表中获得数据,确定数据怎样在应用程序给出。保留字SELECT是DQL(也是所有SQL)用得最多的动词,其他DQL常用的保留字有WHERE,ORDER BY,GROUP BY和HAVING。这些DQL保留字常与其它类型的SQL语句一起使用。
  • 2、数据操作语言(DML:Data Manipulation Language):其语句包括动词INSERT、UPDATE和DELETE。它们分别用于添加、修改和删除。
  • 3、事务控制语言(TCL):它的语句能确保被DML语句影响的表的所有行及时得以更新。包括COMMIT(提交)命令、SAVEPOINT(保存点)命令、ROLLBACK(回滚)命令。
  • 4、数据控制语言(DCL):它的语句通过GRANT或REVOKE实现权限控制,确定单个用户和用户组对数据库对象的访问。某些RDBMS可用GRANT或REVOKE控制对表单个列的访问。
  • 5、数据定义语言(DDL):其语句包括动词CREATE,ALTER和DROP。在数据库中创建新表或修改、删除表(CREATE TABLE 或 DROP TABLE);为表加入索引等。
  • 6、指针控制语言(CCL):它的语句,像DECLARE CURSOR,FETCH INTO和UPDATE WHERE CURRENT用于对一个或多个表单独行的操作。

服务交互图

image.png

  • 连接器:触觉、听觉、嗅觉,好比人能接收外部信号的传感器
  • 缓存:皮毛,能直接快速的过滤掉不必要的传导
  • 分析器:神经细胞,分析接收的信号并传递神经介质给大脑
  • 优化器:纯纯的大脑,数据库牛不牛逼就看脑子灵不灵光了
  • 执行器:大脑下达指令,该怎么做你懂了吗
  • 存储引擎: 就看你脑容量大不大了

那我们就拿pgsql来举个🌰

语法

postgres=# \help SELECT
Command:     SELECT
Description: retrieve rows from a table or view
Syntax:
[ WITH [ RECURSIVE ] with_query [, ...] ]
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
    [ * | expression [ [ AS ] output_name ] [, ...] ]
    [ FROM from_item [, ...] ]
    [ WHERE condition ]
    [ GROUP BY grouping_element [, ...] ]
    [ HAVING condition [, ...] ]
    [ WINDOW window_name AS ( window_definition ) [, ...] ]
    [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
    [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]
    [ LIMIT { count | ALL } ]
    [ OFFSET start [ ROW | ROWS ] ]
    [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]
    [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name [, ...] ] [ NOWAIT | SKIP LOCKED ] [...] ]

from_item 可以是以下选项之一:

    [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]

关键词:SELECT、FROM、WHERE、GROUP、HAVING、ORDER、LIMIT、UNION、WINDOW、WITH

执行顺序及关键点

  1. From Join 锁定范围

FROM 是 SQL 语句执行的第一步。对FROM子句中的前两个表执行笛卡尔积(交叉联接),生成虚拟表VT1,获取不同数据源的数据集。 Q:1.多表关联时哪张表作为驱动表?(join_buffer)2.命中索引时?3.多表(>2)连接顺序?

  1. Where 明确条件

对虚拟表 VT3应用WHERE筛选器。根据指定的条件对数据进行筛选,并把满足的数据插入虚拟表 VT4。由于数据还没有分组,因此现在还不能在WHERE过滤器中使用聚合函数对分组统计的过滤。同时,由于还没有进行列的选取操作,因此在SELECT中使用列的别名也是不被允许的。 Q:为何命中不了索引

  1. Group 找到组织

按GROUP BY子句中的列/列表将虚拟表 VT4中的行唯一的值组合成为一组,生成虚拟表VT5。如果应用了GROUP BY,那么后面的所有步骤都只能得到的虚拟表VT5的列或者是聚合函数(count、sum、avg等)。原因在于最终的结果集中只为每个组包含一行。同时,从这一步开始,后面的语句中都可以使用SELECT中的别名。 Q:数据倾斜?

  1. Agg Func 分析目标

计算 max 等聚合函数。SQL Aggregate 函数计算从列中取得的值,返回一个单一的值

  1. Having 排查结果

对虚拟表VT6应用HAVING筛选器。根据指定的条件对数据进行筛选,并把满足的数据插入虚拟表VT7。HAVING 语句在SQL中的主要作用与WHERE语句作用是相同的,但是HAVING是过滤聚合值,在 SQL 中增加 HAVING 子句原因就是,WHERE 关键字无法与聚合函数一起使用,HAVING子句主要和GROUP BY子句配合使用。

  1. Select 关键信息

将虚拟表 VT7中的在SELECT中出现的列筛选出来,并对字段进行处理,计算SELECT子句中的表达式,产生虚拟表 VT8。将重复的行从虚拟表 VT8中移除,产生虚拟表 VT9。DISTINCT用来删除重复行,只保留唯一的。 Q:回表

  1. Order 得出顺序

将虚拟表 VT9中的行按ORDER BY 子句中的列/列表排序,生成游标 VC10 ;此时返回的一个游标,而不是虚拟表。sql是基于集合的理论的,集合不会预先对他的行排序,它只是成员的逻辑集合,成员的顺序是无关紧要的。对表进行排序的查询可以返回一个对象,这个对象包含特定的物理顺序的逻辑组织。这个对象就叫游标。正因为返回值是游标,那么使用order by 子句查询不能应用于表表达式。排序是很需要成本的,除非你必须要排序,否则最好不要指定order by,最后,在这一步中是第一个也是唯一一个可以使用select列表中别名的步骤。

  1. Limit Offset 决出胜负

从VC10的开始处选择指定数量行,生成虚拟表 VT11,并返回调用者。 Q:深度分页?