本文译自:http://coding-geek.com/how-databases-work

我们使用数据库,直观感受上是客户端发送一个 SQL,数据库把这个SQL执行一下,查出来数据返回给客户端。但其实SQL在背后被转换,优化,历经许多「磨难」才把结果给取回来。

数据库是咋工作的?(一)

如上图, 我们看到是从查询处理器里经过解析器,优化器,才进入的执行引擎。

今天我们先来看查询管理器,后面再重点来看查询的优化器是怎样精打细算的。

查询管理器

这一部分是数据库功能体现。在这部分里,会将写得不好的查询转换成可以快速执行代码, 然后执行它,并将结果返回给客户端。这个过程会包含多个步骤:

  • 首先解析查询是否是合法的

  • 然后会将查询重写,去除没用的操作符,并做一些预优化

  • 对查询优化以提升性能,将查询转换成执行和数据访问计划

  • 编译查询计划

  • 执行

这部分里,对最后两点我们不会说太多,相对来说他俩没那么关键。

查询解析器

每个SQL语句都会经过分析器去校验语法是否正确。如果你写错了,解析器会拒绝查询。比如你手误,把SELECT 写成了 SLECT,那直接会停止在这儿。

此外,还会检查关键词顺序是否正确。

然后,查询SQL中的表名和列名也会分析,解析器会通过数据库的 metadata 来检查以下内容:

  • 表是否存在

  • 表中对应的查询字段是否存在

  • 对应的操作符是不是能作用在指定的列上(比如不能把一个数字和字符串比大小,也不能给一个integer用substring)

之后会检查查询中对应的表你是否有权限去读或写,毕竟这些访问权限是DBA分配的。

在解析的过程中, 查询SQL 会被转换成数据库的内部表示形式(一般是一棵树)。如果一切 OK,这个转换后的内容会发送给查询「重写器」

查询 Rewriter

在这一步,我们拿到了一个查询的内部表示形式,重写器的目标是要:

  • 对查询做预优化

  • 避免无用的操作

  • 帮助优化器发现最佳方案

重写器会对查询执行一系列已知的规则。如果查询符合某个规则的模式,就会应用这个规则来重写查询。以下是(可选)的规则:

  • 视图合并:如果在查询中使用了视图,那视图将会随着该视图的SQL代码进行转换。

  • 子查询打平:有子查询的查询很难优化,因此重写器将尝试修改查询,甚至删除子查询。

例如

SELECT PERSON.*FROM PERSONWHERE PERSON.person_key IN(SELECT MAILS.person_keyFROM MAILSWHERE MAILS.mail LIKE 'christophe%');

就会被这条SQL替换

SELECT PERSON.*FROM PERSON, MAILSWHERE PERSON.person_key = MAILS.person_keyand MAILS.mail LIKE 'christophe%';
  • 去除无用的操作符:如果你用了DISTINCT,但你已经有一个UNIQUE约束以保证数据唯一,那DISTINCT关键字就会被删除。

  • 消除多余的连接:如果你有两次相同的连接条件,因为一个连接条件被隐藏在视图中,或者由于传递性而导致无用的连接,则将其删除。

  • 持续的算术评估:如果查询是需要计算的内容,那么在重写过程中将对其进行一次计算。比如,把WHERE AGE> 10 + 2转换为WHERE AGE> 12,然后将TODATE(“ 日期”)转换为datetime格式的日期

  • (高级)分区修正:如果你使用了分区表,重写器可以找到要使用的分区。

  • (高级)实例化视图重写:如果已经有了和查询子集匹配的实例化视图,重写器会检查该视图是否是最新视图,并修改查询使用实例化视图而不是原始表。

  • (高级)自定义规则:如果你创建了重写查询的自定义规则,那重写器会执行这些规则(高级)Olap转换:分析/窗口函数,星型连接,汇总…也都会进行转换(但是具体是由重写器还是优化器完成的取决于数据库,因为这两个过程邻近)。

这个重写后的查询会发送给查询优化器,有趣的来了。

统计

在进入数据库如何优化查询之前,我们需要先谈谈统计信息,因为没有统计信息,数据库就会很傻。如果你不告诉数据库分析自己的数据,它不会这样做,而且会做出错误的假设。

那数据库需要什么信息呢?

我们大概说一下论数据库和操作系统如何存储数据的。他们使用的最小单位称为页或块(默认为4或8 KB)。也就是说,如果你只需要1 KB,也会占一页。如果页面占用8 KB,那就会浪费7 KB。

回到统计来,当你要求数据库获取统计信息时,它会计算这些内容:

  • 一个表中的行或页的数量

  • 一个表里的每一列

    • 单独的数据内容

    • 数据的长度(最小,最大,平均)

    • 数据区间信息(最小、最大、平均)

  • 表的索引信息

这些统计信息会帮助优化器更好的预估查询中磁盘I/O,CPU以及内存的使用。

每一列的统计信息都很重要。比如一个 PERSON 表,需要在 LAST_NAME, FIRST_NAME两列做连接,通过统计,数据库能知道FIRST_NAME这一列共多少个不同的值,LAST_NAME有多少个不同的值。所以数据库会使用LAST_NAME,FIRST_NAME来连接,而不是FIRST_NAME,LAST_NAME,因为LAST_NAME不太可能相同,会少产生数据。大多数情况下,数据库的前两三个字符比较 LAST_NAME就足够了。

当然这些是基本的统计信息,你也可以让数据库计算 histograms 这种更高阶的统计数据。最常使用的值,质量等等,通过这些附加信息,可以帮助数据库找到更高效的查询计划,特别是像等值查询,以及范围查询这种。因为数据库已经知道这种情况下有多少条记录。

这些统计信息记录在数据库的元数据中。因此也是需要花时间不断更新的。这也是为啥在大多数数据库里他都不自动更新。

后面的文章,会描述查询优化器的一些细节。

读完这部分之后,扩展阅读:

  • The initial research paper (1979) on cost based optimization: Access Path Selection in a Relational Database Management System. This article is only 12 pages and understandable with an average level in computer science.

  • A very good and in-depth presentation on how DB2 9.X optimizes queries here

  • A very good presentation on how PostgreSQL optimizes queries here. It’s the most accessible document since it’s more a presentation on “let’s see what query plans PostgreSQL gives in these situations“ than a “let’s see the algorithms used by PostgreSQL”.

  • The official SQLite documentation about optimization. It’s “easy” to read because SQLite uses simple rules. Moreover, it’s the only official documentation that really explains how it works.

  • A good presentation on how SQL Server 2005 optimizes queries here

  • A white paper about optimization in Oracle 12c here

  • 2 theoretical courses on query optimization from the authors of the book “DATABASE SYSTEM CONCEPTS”here and there. A good read that focuses on disk I/O cost but a good level in CS is required.

  • Another theoretical course that I find more accessible but that only focuses on join operators and disk I/O.

相关阅读

MySQL: 喂,别走,听我解释一下好吗?

数据库是咋工作的?(一)

凭什么让日志先写?

Java七武器系列长生剑 -- Java虚拟机的显微镜 Serviceability Agent

Java七武器系列霸王枪 -- 线程状态分析 jstack

Java七武器系列孔雀翎-- 问题诊断神器BTrace

嵌套事务、挂起事务,Spring 是怎样给事务又实现传播特性的?

怎样阅读源代码?

如果你觉也还可以,来个在看或转发吧,多谢!

源码|实战|成长|职场

这里是「Tomcat那些事儿」

请留下你的足迹

我们一起「终身成长」

一个数据库SQL查询的数次轮回相关推荐

  1. Python学习日志16 - 数据库SQL查询

    Python学习日志 RBHGO的主页欢迎关注 温馨提示:创作不易,如有转载,注明出处,感谢配合~ 目录 文章目录 Python学习日志 目录 Python学习日志16课 - 数据库SQL查询 DQL ...

  2. 视频教程-数据库SQL查询,最佳案例讲解-SQL Server

    数据库SQL查询,最佳案例讲解 教学风格独特,以学员视角出发设计课程,难易适度,重点突出,架构清晰,将实战经验融合到教学中.讲授技术同时传递方法.得到广大学员的高度认可. 王进 ¥19.00 立即订阅 ...

  3. 一个 提高SQL 查询的讨论帖

    idn(关键字),产品名称,产品数量... B表,有字段:idn,a_idn(记录A表的关键字),工序,工时... A表与B表是一对多的关系, 我想取到A表的明细及B表相关的总工时 sele aa.* ...

  4. 数据库SQL查询练习

    --重点推荐使用natural join,inner join!!!,尽量避免使用广义的笛卡尔积 --重点推荐使用natural join,inner join!!!,尽量避免使用广义的笛卡尔积 -- ...

  5. PostgreSQL数据库sql查询如何获取汉字拼音首字母

    一.前言 在实际开发过程中,经常会使用模糊查询,根据某个关键字模糊搜索,一般是 name like '%123%' 这样查,但是如果某个关键字用户不记得呢,只知道首字母,又如何模糊查询呢?例如,查询 ...

  6. [数据库] SQL查询语句表行列转换及一行数据转换成两列

    本文主要讲述了SQL查询语句表之间的行列转换,同时也包括如何将一行数据转换成两列数据的方法.子查询的应用.decode函数的用法.希望文章对你有所帮助~ 1.创建数据库表及插入数据 2.子查询统计不同 ...

  7. WordPress 常用数据库SQL查询语句大全

    https://www.wpdaxue.com/wordpress-sql.html 在使用WordPress的过程中,我们少不了要对数据库进行修改操作,比如,更换域名.修改附件目录.批量修改文章内容 ...

  8. sql server整表查询慢_这里有一个慢 SQL 查询等你来优化

    背景 最近工作上遇到一个"神奇"的问题, 或许对大家有帮助, 因此形成本文. 问题大概是, 我有两个表 TableA, TableB, 其中 TableA 表大概百万行级别(存量业 ...

  9. 一个Spark SQL查询的一生

    Spark是时下很火的计算框架,由UC Berkeley AMP Lab研发,并由原班人马创建的Databricks负责商业化相关事务.而SparkSQL则是Spark之上搭建的SQL解决方案,主打交 ...

最新文章

  1. valgrind——Cachegrind分析CPU的cache命中率、丢失率,用于进行代码优化。
  2. ISLR线性回归笔记
  3. java 实现二叉树操作
  4. [云炬创业基础笔记] 第四章测试16
  5. 配置审计(Config)配合开启OSS防盗链功能
  6. 校验用户手机号是否合法
  7. 100g流量在电脑上可以用多久_三大运营商5G体验方案出炉!100G一个月够不够?...
  8. finalize方法_final,finally,finalize三者的含义和区别
  9. 多重背包单调队列优化思路_多重背包问题
  10. 20179209《Linux内核原理与分析》第一周作业
  11. c++类的成员函数作回调函数为啥要声明为static的
  12. 魔兽世界MPQ加载顺序
  13. Linux搭建FTP服务器
  14. Android studio基础练习02【监听器实现下拉菜单】
  15. 这里带你了解IR2104驱动电路
  16. 计算机无法访问inter,电脑网络提示无Internet访问权限解决办法
  17. 【微信小程序】条件渲染和列表渲染
  18. 条码和自动识别的基础知识
  19. (复现)CVE-2021-21985 Vmware vcenter远程代码执行RCE
  20. strace命令用法详解

热门文章

  1. 唯品会按关键字搜索商品API,Onebound数据接口
  2. BSDS500数据集边缘检测任务结果评估
  3. ThinkPHP5实现定时器任务
  4. 无法截断表 ‘tbl_******** ‘,因为该表正由 FOREIGN KEY 约束引用
  5. 期货开户充分了解交易制度
  6. 【Reinforcement Learning】策略学习
  7. 计算机组成原理-作业四
  8. 捷豹路虎旗下的全新捷豹XFL适合商务人士吗?
  9. 如何创建项目变更管理流程?
  10. 如何管理90后员工?