文章目录

  • 8 查询优化
    • 8.1 概述
    • 8.2 查询数和语法树
    • 8.3 代数优化
    • 8.4 物理优化
    • 8.5 连接操作优化
      • 8.5.1 嵌套循环法
      • 8.5.2 利用B+树索引或哈希索引寻找匹配元组法
      • 8.5.3 散列连接法
    • 8.6 后话

8 查询优化

8.1 概述

我们不管是在数据库软件如MySQL、SQLServer等,还是通过应用程序连接数据库如JDBC、ODBC等。本质上我们如果要查询数据库中的数据,都是使用SQL去查询。而这个查询的过程说大不大说小不小,如果数据库中一个表内含有许多数据,一个数据库含有很多个表,那么你的SQL写法将大大影响到你查数据的效率。

查询优化并不是由用户决定的,而是由DBMS决定的。当用户写了一条SQL语句后,查询系统会对SQL语句做一个重写,然后变成一个执行效率更高的形式。

换而言之,如果你在数据库中写入了select e.ENAME,d.DNAME from emp e (inner) join dept d on e.DEPTNO = d.DEPTNO;这样的查询语句,实际上传入数据库时,DBMS会自动帮你改写为效率更高的SQL语句。

查询优化一般从四个方面入手:

  • 把查询语句进行变换,改变基本操作的次序,然后查询起来更加有效,这个叫做代数优化
  • 根据系统所提供的存取路径,选择合理的存取策略,也就是对存取的方法进行优化,我们叫做物理优化
  • 有限查询优化根据启发式规则和选择执行的策略去先做选择,投影等一元操作,然后做连接操作,这叫规则优化,代数优化和物理优化属于规则优化。
  • 在很多的优化策略里面,选取代价最小的优化执行策略,叫做代价估算优化

需要注意的是,虽然DBMS会帮你重写查询语句,但是如果重写的过程比原SQL查询的过程还久,那显然不合适。

8.2 查询数和语法树

数据库查询语言的处理过程和一般高级程序设计语言相仿。都是经历了解释和编译的过程。

让我们看回这个图。应用调用接口传入命令语句,词法和语法分析器会去解释命令语句,在这里他就会用到一个语法树,将命令语句转变为SQL语句,然后授权检查是否有权限;当有权限后,就会执行sql语句,这里就涉及到查询优化的问题了,其会利用查询树来优化该SQL语句。

8.3 代数优化

代数优化是对查询进行等效变换,以减少执行的开销。最常用的变化原则是,尽量缩短查询过程中的中间结果。由于选择、投影等一元操作分别从水平方向或垂直方向减少关系的大小,而连接、并等二元操作本身的开销较大,而且很可能产生大的中间结果。因此在变换查询时,我们让选择和投影先做,再做二元操作。在连接时,也是先做小关系之间的连接,再做大关系的连接。在有些DBMS中还会找出查询中相同的部分,统一处理,以避免重复运算,还有些DBMS把嵌套查询变为非嵌套查询。

简单来说,假如现在有两张10000个元组的表,想做查询和连接两个操作,根据笛卡尔乘积现象,简单来说,假如现在有两张10000个元组的表,根据笛卡尔乘积现象,当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的乘积。也就是要做10000乘以10000次乘积,这无疑是很大的,那如果我们根据选择操作先筛选掉一部分,然后在做连接操作,那么执行效率就会大大提高。

8.4 物理优化

代数优化只是在各种操作中变换次序达到提高效率的目的,虽然这样很方便,但是优化效果有限。但是如果通过合理选择存取路径,往往能够收到显著的优化效果。

在7.1我们谈到过,对于关系小的,查询量大的,我们可以用最原始的方法——顺序扫描,按照关系存放的自然顺序读取各元组,然后按选择条件检验,选取那些满足条件的元组。但是这种方法对于关系大的显然不适用。在目前,用得最多的存储方式就是利用B+树或其变种为结构的各种索引来提高查询的效率。

8.5 连接操作优化

在高级数据库工程师考试中,常见的就是考查连接操作优化。其优化方式有以下几种:

  • 嵌套循环法

  • 利用索引或散列寻找匹配元组法

  • 排序归并法

  • 散列连接法

8.5.1 嵌套循环法

大体来说他像我们编程语言里面的循环嵌套一样。假如现在有两个关系(表):R和S,如下图所示:

如果说我们要进行连接操作,本质上连接操作就是加了条件的笛卡尔乘积。那么我们是利用嵌套循环法就是先用R中的一条元组去匹配另外S表中的所有元组(S表中的所有元组相当于内层循环),然后R中的第二条元组再去匹配S中的所有元组,以此类推,直到R的所有元组和S的所有元组比较完为止。

在整个连接过程中,R只要扫描一次,S就要扫描n次(也就是S表中所有的元组),从程序设计的观点来看,R的扫描相当于程序的外循环,而S相当于程序的内循环,因此我们把R叫做外关系,S叫做内关系。当然,两张表的地位可以互换,这取决于两者扫描的IO代价。

在前面的章节中,我们曾经谈论过磁盘。如果说R中表中一条匹配S表中一条元组就要I/O一次,那么这显然是效率极低的。但是实际上,在操作系统中硬盘是一种块设备,他是以物理块为单位,也就是说,假如一个物理块是1040M,R中一条元组为100M,那么一个物理块就可以容纳R中十条元组去匹配S表。

我们可以设置两个缓冲区,分为外循环和内循环。

外循环的缓冲区可以存放外循环的物理块,内循环的缓冲区可以存放内循环的物理块,当两张表做连接,我们采用循环嵌套法的时候,我们不再是一条一条元组匹配,而是如上所说一个物理块匹配内循环的一个物理块,如果当你内存足够大,你可以设置足够大的缓冲区,存放更多的物理块,如果这张表不大,甚至能做到一波全部匹配完,大大减少了匹配效率。

8.5.2 利用B+树索引或哈希索引寻找匹配元组法

我们在两个表中还是那样:

R表作为外循环,S表作为内循环,然后给R表一个缓冲区,S表带有B+树索引。

之后R表一个物理块读进来,他要找S表中匹配的元组,就可以通过B+树索引找到物理块中符合连接条件的元组的地址,直接进行匹配,大大节省了寻找匹配元组的效率,不需要像嵌套循环法那样去扫描。

但是这个需要考虑代价:假如在某个属性上面,重复值的数量达到了总元组数的百分之二十以上的话,用索引反而不合算。什么意思呢?如果有过多的重复值,也就意味着你要在建树的时候有许多重复值,这就会导致在辨别重复值的时候花费过多的代价,这样还不如使用循环嵌套法来的方便。

8.5.3 散列连接法

具体来说就是:他把R表和S表中以后做连接有可能产生的结果全部哈希到一个柜子里,柜子有多个抽屉,不同的抽屉代表不同的结果,以后只要需要两张表的连接,只需要在哈希出来的这个柜子(表)里面去找就行了。

但是考虑到代价,也就是说你这个R表和S表不会频繁的去更新,否则的话会打乱哈希出来的表,定期做维护代价也会很大。

8.6 后话

实际上,查询优化博大精深,但是对于初学者来说,这一讲并不是其需要学习的重点,而对于数据库老手,我更建议去看数据库原书或者是东南大学王能斌老师的书。这里还有很多的知识我就不再细讲了,有兴趣的同学可以去自行探究。

数据库杂谈(八)——查询优化相关推荐

  1. 数据库杂谈(五)——关系数据库语言

    文章目录 5 关系数据库语言 5.1 MySQL简介 5.1.1 MySQL的发展历史 5.1.2 数据库的用户接口 5.1.3 SQL及其概念辨析 5.1.4 SQL查询语言的分类 5.2 入手 5 ...

  2. 探索Oracle之数据库升级八 12c Downgrade 11gR2

    探索Oracle之数据库升级八 12c Downgrade 11gR2 前言: 我们前面已经完毕了11gR2 upgrade to 12c 的升级,整个过程还是比較顺利的,尽管和曾经版本号升级有些不太 ...

  3. Mysql数据库(八)——mysql高阶语句(中)

    Mysql数据库(八)--mysql高阶语句(中) 一.正则表达式(同shell脚本的正则表达式) 1.以"."代替任意一个字符 2.匹配前面字符多次 3.匹配前面字符至少一次 4 ...

  4. Mysql数据库(八)排名函数

    Mysql数据库(八)排名函数 mysql中排名函数有三个 1.row_number():表示排序,成绩相同,也不重复 2.rank():表示排序,成绩相同,排名重复,但跳跃 3.dense_rank ...

  5. SQL性能优化中的底层概念,时间复杂度,算法和数据结构,数据库组成,查询优化和表关联原理.

    原文地址: http://blog.jobbole.com/100349/ 一提到关系型数据库,我禁不住想:有些东西被忽视了.关系型数据库无处不在,而且种类繁多,从小巧实用的 SQLite 到强大的 ...

  6. 数据库杂谈(二)——数据模型

    今天的你也要快乐! 文章目录 2 数据模型 2.1 层次数据模型 2.1.1 基础概念 2.1.2 结构 2.1.3 虚拟记录 2.2 网状数据模型 2.2.1 基本概念 2.2.2 联系记录 2.2 ...

  7. oracle如何读取到从n行到m行的数据_关系型数据库进阶之查询优化

    点上面"东哥IT笔记",关注并星标 每天一篇业界最新技术分享 在前面几篇文章中,我们已经介绍了总体构架,客户端管理和查询管理.在查询管理中,有一个很重要的部分我们没有介绍,那就是查 ...

  8. 面试题 之 数据库部分 八

    面试题 之 Java基础部分 八 1.用两种方式根据部门号从高到低,工资从低到高列出每个员工的信息. select * from emp order by deptid desc, salary as ...

  9. 【达梦数据库】DM 查询优化

    文章目录 前言 一.思路与目标 1.1 优化基本思路 1.2 查询优化步骤 1.3 查询优化目的 二.查询优化器 2.1 查询转换 2.2 估算代价 2.3 生成计划 2.4 数据访问路径 2.5 连 ...

最新文章

  1. Linux内存管理 (2)页表的映射过程
  2. LCD显示原理和驱动方式介绍
  3. Ubuntu下使用中文语言
  4. 获得主机域名及其IP和Port端口
  5. python 表白程序代码_python抖音表白程序源代码
  6. Apache POI学习笔记
  7. 面向对象-类与对象、关键字、异常使用
  8. 1.4.1用空间向量研究直线、平面的位置关系教学设计
  9. SIFT原作者David Lowe主页
  10. Android Launcher负一屏实现方案
  11. java学习之springcloud之服务注册与发现篇
  12. 【软件设计】CS客户端整体架构
  13. Dingoapi的使用
  14. 抠图技术及方法简介(Image Matting Overview)
  15. Qt在VS中的使用方法详解
  16. 加密解密,MySQL单行函数,数学函数字符串日期时间,流程控制,完整详细可收藏查询SQL
  17. 小波变换 完美通俗解读【转载
  18. 【论文阅读|cryoET】Isotropic reconstruction for electrontomography with deep learning (解决缺失楔问题降噪)
  19. Deep Face Recognition论文翻译
  20. 飞凌嵌入式 RK3399核心板 iMX6ULL核心板 iMX6UL核心板 PX30,RK3368,RK3288,RK3399,i.mx6芯片参数对比分析

热门文章

  1. debian下安装repo
  2. VSS2005 上传pdf 空白
  3. Bitmap 之 getPixels() 的 stride
  4. I AM NOTHING vs I AM SOMETHING
  5. plotly django_使用Plotly为Django HTML页面进行漂亮的可视化
  6. 预测股票价格 模型_建立有马模型来预测股票价格
  7. leetcode 179. 最大数(排序)
  8. Java—简单的注册页面
  9. leetcode915. 分割数组
  10. leetcode1144. 递减元素使数组呈锯齿状