一个数据库SQL查询的数次轮回 百度智能云正式对外发布百度智能云数据库品牌GaiaDB 数据库三大泛式是什么 电力行业网管需求 IT运维管理解决方案 citrix桌面虚拟化中的运维工具Director SRE运维体系的构建和工作职责划分 运维的核心价值是什么 手游开发定制的全过程详解 开发人员透露:《赛博朋克2077》枪支泛滥 成熟的产品经理如何应对“这个需求不合理” CI/CD管道对开发和运维的重要性 APP开发的流程是怎样的 如何开发一个APP 零基础学web前端开发要学多久 如何系统学习 Web前端要学习哪些内容呢 前端工程师至少要满足四类客户的需求 前端学习计划思维导图 前端人如何选择自己的技术栈 前端人如何更快地成长 大数据的七大核心具体价值 核心价值究其用户到底是谁 大数据核心技术是什么 该怎么掌握Hadoop知识 未来大数据应用场景广阔 中国将成为全球最大的数据圈 2020大数据产业生态大会通过“现场论道+云端连线”全程直播的方式在北京举行 2020中国大数据生态产业大会 华为云大数据连续四年荣登50强榜首 中国电信全面提速大数据新基建 无法启动计算机时该怎么办 通过这6个专业技巧来加速计算机 计算机专家提供在家工作或学习的技巧 2020年空中数据计算机市场新战略报告:技术进步,趋势与增长 物联网分析市场前景2020-2025年最新发展数据和市场趋势预测 马来西亚主要供应商的物联网(IoT)安全市场规模和增长 2020年医疗保健行业的物联网(IoT)市场分析以及到2025年的未来需求 零售市场类型和应用中的物联网(IoT)展望和2025年预测 蒙特利尔华纳兄弟公司正在寻找新程序员 而工作就是玩家的天堂 世界各地的5位著名女程序员 代码中的AI:AI对开发人员做了什么 如何找到程序员的第一份工作 盲人程序员创建没有图形的手机游戏 花费不到30美元 即可成为拥有30小时教程的专家Python程序员
您的位置:首页 >数据库 >

一个数据库SQL查询的数次轮回

我们使用数据库,直观感受上是客户端发送一个 SQL,数据库把这个SQL执行一下,查出来数据返回给客户端。但其实SQL在背后被转换,优化,历经许多「磨难」才把结果给取回来。
  如上图, 我们看到是从查询处理器里经过解析器,优化器,才进入的执行引擎。
  今天我们先来看查询管理器,后面再重点来看查询的优化器是怎样精打细算的。
  查询管理器
  这一部分是数据库功能体现。在这部分里,会将写得不好的查询转换成可以快速执行代码, 然后执行它,并将结果返回给客户端。这个过程会包含多个步骤:
  ·首先解析查询是否是合法的
  ·然后会将查询重写,去除没用的操作符,并做一些预优化
  ·对查询优化以提升性能,将查询转换成执行和数据访问计划
  ·编译查询计划
  ·执行
  这部分里,对最后两点我们不会说太多,相对来说他俩没那么关键。
  查询解析器
  每个SQL语句都会经过分析器去校验语法是否正确。如果你写错了,解析器会拒绝查询。比如你手误,把SELECT 写成了 SLECT,那直接会停止在这儿。
  此外,还会检查关键词顺序是否正确。
  然后,查询SQL中的表名和列名也会分析,解析器会通过数据库的 metadata 来检查以下内容:
  ·表是否存在
  ·表中对应的查询字段是否存在
  ·对应的操作符是不是能作用在指定的列上(比如不能把一个数字和字符串比大小,也不能给一个integer用substring)
  之后会检查查询中对应的表你是否有权限去读或写,毕竟这些访问权限是DBA分配的。
  在解析的过程中, 查询SQL 会被转换成数据库的内部表示形式(一般是一棵树)。如果一切 OK,这个转换后的内容会发送给查询「重写器」
  查询 Rewriter
  在这一步,我们拿到了一个查询的内部表示形式,重写器的目标是要:
  ·对查询做预优化
  ·避免无用的操作
  ·帮助优化器发现最佳方案
  重写器会对查询执行一系列已知的规则。如果查询符合某个规则的模式,就会应用这个规则来重写查询。以下是(可选)的规则:
  视图合并:如果在查询中使用了视图,那视图将会随着该视图的SQL代码进行转换。
  子查询打平:有子查询的查询很难优化,因此重写器将尝试修改查询,甚至删除子查询。
  例如:
  SELECT PERSON.* 
  FROM PERSON 
  WHERE PERSON.person_key IN 
  (SELECT MAILS.person_key 
  FROM MAILS 
  WHERE MAILS.mail LIKE 'christophe%'); 
  就会被这条SQL替换
  SELECT PERSON.* 
  FROM PERSON, MAILS 
  WHERE PERSON.person_key = MAILS.person_key 
  and 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 这种更高阶的统计数据。最常使用的值,质量等等,通过这些附加信息,可以帮助数据库找到更高效的查询计划,特别是像等值查询,以及范围查询这种。因为数据库已经知道这种情况下有多少条记录
  这些统计信息记录在数据库的元数据中。因此也是需要花时间不断更新的。这也是为啥在大多数数据库里他都不自动更新。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。