一条sql是如何执行的详解

一条sql是如何执行的详解

1. SQL 解析(Parsing)

2. 查询重写(Query Rewrite)

3. 查询规划(Query Planning)

4. 查询执行(Query Execution)

5. 结果返回

示例:查询执行流程

总结


🎈边走、边悟🎈迟早会好

一条 SQL 查询在 PostgreSQL(以及大多数关系型数据库)中的执行过程可以分为多个阶段。每个阶段都对应特定的任务,从 SQL 解析到最终获取查询结果。以下是 SQL 查询执行过程的详细拆解:

1. SQL 解析(Parsing)

当用户提交一条 SQL 语句后,PostgreSQL 首先进入解析阶段。这个阶段主要有以下几个步骤:

  • 词法分析:首先,SQL 语句被分解为单独的词法单元(tokens),如关键字、表名、列名、操作符等。
  • 语法分析:接下来,解析器(parser)根据 SQL 语法规则,检查 SQL 语句是否符合 SQL 语法。例如,SELECT 是否紧跟着字段名等。
  • 语义分析:如果语法检查通过,系统会进行语义分析。例如,验证表名和列名是否存在于数据库的元数据中。

输出:在这个阶段,SQL 语句被转换为一个内部的解析树(parse tree)。

2. 查询重写(Query Rewrite)

在解析树生成后,PostgreSQL 会检查是否有任何规则(rules)适用,并根据这些规则对查询进行重写。重写规则(如视图的定义)可能会改变原始的 SQL 查询,生成新的查询树。

例如:

  • 当你查询视图时,查询会被重写为对基础表的查询。
  • 应用触发器或规则也可能会重写查询。

输出:生成经过重写的查询树。

3. 查询规划(Query Planning)

这个阶段,查询规划器(Query Planner)负责将重写后的查询树转换为执行计划。查询规划器会决定如何最有效地访问数据,主要涉及以下步骤:

  • 候选执行计划生成:查询规划器生成多个可能的执行计划。例如:
    • 使用顺序扫描(Sequential Scan)扫描表中的所有行。
    • 使用索引扫描(Index Scan)根据索引快速定位数据。
    • 是否需要执行连接(JOIN)操作,以及选择哪种连接算法(嵌套循环、哈希连接、归并连接)。
  • 成本估算(Cost Estimation):查询规划器会为每个候选计划估算成本。成本基于以下因素:
    • I/O 成本:数据从磁盘读取到内存的成本。
    • CPU 成本:处理每行数据的计算成本。
    • 行数估计:查询中每个步骤的结果集大小估计。

PostgreSQL 使用统计信息(如表中行的数量、索引的选择性、列的分布等)来进行成本估算。

  • 选择最佳计划:根据每个执行计划的估算成本,选择成本最低的执行计划。

输出:生成最终的执行计划(execution plan),这是系统决定如何执行查询的详细步骤。

4. 查询执行(Query Execution)

一旦执行计划确定下来,查询执行器(Query Executor)开始按照计划一步步执行操作。主要的执行步骤包括:

  • 扫描(Scan):执行器按照计划选择的扫描方式(如顺序扫描、索引扫描)读取数据。

    • 如果是顺序扫描,则逐行读取表中的数据。
    • 如果是索引扫描,则使用索引来定位特定的行。
  • 过滤(Filter):对于每一行数据,执行器会根据 WHERE 子句条件进行过滤,确保仅保留符合条件的行。

  • 连接(Join):如果查询涉及多个表,执行器会根据选择的连接算法(如嵌套循环连接、哈希连接)对这些表的数据进行连接处理。

  • 排序(Sort)和分组(Group):如果查询要求对数据进行排序(ORDER BY)或分组(GROUP BY),执行器会在获取数据后进行这些操作。

  • 投影(Projection):执行器会根据 SELECT 子句中的字段选择要返回的列,并忽略未被选中的列。

  • 返回结果:最终结果集根据执行计划一步步执行并返回给客户端。

5. 结果返回

执行器生成的结果集会逐行或批量地返回给客户端,直到所有匹配的记录都返回。

示例:查询执行流程

假设你有一个简单的查询:

SELECT name, salary FROM employees WHERE department_id = 10 ORDER BY salary DESC;
  1. SQL 解析

    • 解析器将 SQL 拆解为标识符:SELECTnamesalaryemployeesWHEREdepartment_idORDER BYDESC
    • 检查 employees 表是否存在,namesalarydepartment_id 是否是合法字段。
  2. 查询重写

    • 如果 employees 是一个视图,SQL 会被重写为查询基础表。
  3. 查询规划

    • PostgreSQL 会分析是否有适合 department_id 的索引。如果有索引,可以使用索引扫描来提高效率。
    • 生成多个候选计划,例如顺序扫描、索引扫描,并计算各自的成本。
    • 选择成本最低的计划。假设选择了索引扫描方式。
  4. 查询执行

    • 执行器根据选择的计划,使用索引扫描从 employees 表中查找 department_id = 10 的记录。
    • 过滤不符合条件的行。
    • 根据 salary 列对数据进行排序。
  5. 结果返回

    • salary 排序后的记录逐行返回给客户端。

总结

SQL 查询的执行过程分为解析、查询重写、查询规划、查询执行和结果返回五个主要步骤。每个步骤都对应特定的任务,从解析 SQL 到最终返回结果,确保查询尽可能高效地执行

 🌟感谢支持 听忆.-CSDN博客

🎈众口难调🎈从心就好

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/53863.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB | R2024b更新了哪些好玩的东西?

Hey, 又到了一年两度的MATLAB更新时刻,MATLAB R2024b正式版发布啦!,直接来看看有哪些我认为比较有意思的更新吧! 1 小提琴图 天塌了,我这两天才写了个半小提琴图咋画,MATLAB 官方就出了小提琴图绘制方法。 小提琴图…

鸿蒙读书笔记1:《鸿蒙操作系统设计原理与架构》

笔记来自新书:《鸿蒙操作系统设计原理与架构》 HarmonyOS采用分层架构,从下到 上依次分为内核层、系统服务层、框架层和应用层。 1. 内核层 内核层主要提供硬件资源抽象和常用软件资源,包括进程/线程管 理、内存管理、文件系统和IPC&#xff…

Unity教程(十五)敌人战斗状态的实现

Unity开发2D类银河恶魔城游戏学习笔记 Unity教程(零)Unity和VS的使用相关内容 Unity教程(一)开始学习状态机 Unity教程(二)角色移动的实现 Unity教程(三)角色跳跃的实现 Unity教程&…

C语言开发一个简单的产品入库操作系统

编写一个简单的产品入库操作系统是一个涉及文件操作、用户输入和数据处理的项目。以下是一个基本的C语言示例,它展示了如何创建一个简单的产品入库系统。这个系统将允许用户添加产品信息,并将其存储在文件中。 功能描述 添加产品信息(产品I…

react js 路由 Router

完整的项目,我已经上传了 资料链接 起因, 目的: 路由, 这部分很难。 原因是, 多个组件,进行交互,复杂度比较高。 我看的视频教程 1. 初步使用 安装: npm install react-router-dom 修改 index.js/ 或是 main.js 把 App, 用 BrowserRouter 包裹起来 2. Navigate 点击…

无关痛痒的return 0

一般我们在程序的最后都要加上一行代码: return 0; 它通常用于main函数的末尾来表示程序正常结束。如果返回0以外的任何数,就表示程序没有正常结束。假使你在竞赛时一时兴起想要标新立异来个return 9527,那么你就悲剧了。 其实这玩艺完全可…

redis基本数据类型和常见命令

引言 Redis是典型的key-value(键值型)数据库,key一般是字符串,而value包含很多不同的数据类型: Redis为了方便我们学习,将操作不同数据类型的命令也做了分组,在官网( Commands | Do…

TS 常用类型

我们经常说TypeScript是JavaScript的一个超级 TypeScript 常用类型 TypeScript 是 JS 的超集,TS 提供了 JS 的所有功能,并且额外的增加了:类型系统 所有的 JS 代码都是 TS 代码 JS 有类型(比如,number/string 等&…

《JavaEE进阶》----14.<SpringMVC配置文件实践之【验证码项目】>

本篇博客介绍的是Google的开源项目Kaptcha来实现的验证码。 这种是最简单的验证码。 也是很常见的一种验证码。可以去看项目结果展示。就可以明白这个项目了。 前言: 随着安全性的要求越来越高、很多项目都使用了验证码。如今验证码的形式也是有许许多多、更复杂的图…

LeetCode: 673.最长子序列的数量 动态规划 时间复杂度O(n*n)

673.最长子序列的数量 LeetCode原题连接 673. 最长子序列的数量 题目描述 给定一个未排序的整数数组,找到最长递增子序列的个数。 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和 [1, 3, 5, 7]。示例 2: 输…

基于SpringBoot的古城墙景区管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的古城墙景区管理系…

用go语言实现树和哈希表算法

算法复杂度 判断一个算法的效率通常基于其计算复杂度,这主要与算法访问输入数据的次数有关。计算机科学中常用大O表示法来描述算法的复杂度。例如,O(n)的算法只需访问一次输入数据,因此优于O(n)的算法,后者则优于O(n)的算法&…

2024数学建模国赛官方评阅标准发布!

​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑…

C++类与对象(下)--最后的收尾

内部类 • 如果⼀个类定义在另⼀个类的内部&#xff0c;这个内部类就叫做内部类。内部类是⼀个独⽴的类&#xff0c;跟定义在 全局相⽐&#xff0c;他只是受外部类类域限制和访问限定符限制&#xff0c;所以外部类定义的对象中不包含内部类。 #include<iostream> using…

JS中的indexOf与Set(其实是引用类型比较的问题)

起因是想在一个二维数组中查找是否包含一个一维数组 indexOf 先看个例子&#xff1a; const arr [[1, 1], [2, 2]] if(arr.indexOf([1, 1]) -1){console.log("无法查到该数组") }else{console.log("已找到") }const arr2 [1,2,3,4,5] if(arr2.index…

安装FTP服务器教程

一。安装vsftpd yum install vsftpd 二。修改配置文件&#xff0c;匿名账户具有访问&#xff0c;上传和创建目录的权限 vim /etc/vsftpd/vsftpd.conf &#xff08;红色进行设置放开YES&#xff09; local_enable&#xff1a;本地登陆控制&#xff0c;no表示禁止&#xff0c;ye…

3. 轴指令(omron 机器自动化控制器)——>MC_MoveAbsolute

机器自动化控制器——第三章 轴指令 4 MC_MoveAbsolute变量▶输入变量▶输入输出变量▶输入输出变量 功能说明▶指令详情▶时序图▶重启运动指令▶多重启动运动指令▶异常 示例程序1▶参数设定▶动作示例▶梯形图▶结构文本(ST) 示例程序2▶参数设定▶动作示例▶梯形图▶结构文…

Python 从入门到实战16(正则表达式语法)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们通过举例学习了字符串一些操作说明。今天讨论一下正…

RDMA应用场景及效果

GPU Direct 参考&#xff1a;网络架构如何支持超万卡的大规模 AI 训练&#xff1f;| AICon_芯片与网络_InfoQ精选文章 GPU 网络的情况已经发生了很大变化。每个 GPU 都有自己的内部互联&#xff0c;例如 NVIDIA 的 A100 或 H800&#xff0c;它们内部的 NVLink 互联可以达到 6…

【Kubernetes】常见面试题汇总(六)

目录 17.简述 kube-proxy ipvs 和 iptables 的异同&#xff1f; 18.简述 Kubernetes 中什么是静态 Pod&#xff1f; 19.简述Kubernetes中 Pod 可能位于的状态&#xff1f; 17.简述 kube-proxy ipvs 和 iptables 的异同&#xff1f; &#xff08;1&#xff09;iptables 与 IP…