数据库查询处理及优化

Posted 朱国柱点滴回忆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库查询处理及优化相关的知识,希望对你有一定的参考价值。

时间:2020.03.23

地点:陆河

主题:关系数据库查询处理及优化


【查询操作】是数据库最常用数据操作,查询速度快慢直接影响数据库系统(DBS)执行效率。为提高系统效率,必须提高查询效率。本文介绍关系型数据库相关查询优化技术;

首先介绍关系数据库管理系统【查询处理】步骤,然后再介绍查询优化】相关技术

查询优化技术有2种:

(1)代数优化:通过关系代数表达式优化;

(2)物理优化:涉及底层数据存储路径底层操作算法选择优化;


1查询处理

2查询优化



1.【查询处理】

(1)关系数据库查询处理步骤;

(2)实现查询操作的算法

1.1.1关系数据库查询处理步骤

1.1.2实现查询操作的算法

RDBMS中查询主要涉及操作有:

选择投影连接,其中比较简单,这里不介绍;

介绍选择+连接实现所用到各种算法;


(1)选择的实现算法

    a.全表扫描

    b.索引(或散列)扫描

【例1-1】

select * from student where <where_condition> 中的where子句有: a. 无where子句; b. Sname='zhuguozhu'; c. Sage > 30; d. Sname='zhuguozhu' and Sage > 20;


  1、全表扫描:对查询基表逐行进行扫描,逐一检查每个元组是否满足

where子句中给出的条件,把满足条件的元组作为结果进行输出。

  2、索引(或散列)扫描:如果条件表达式的选择属性列上,建立了索引,可以用索引扫描方法。通过数据库中的索引首先找到满足的元组的指针,再通过指针直接在查找基本表中找到满足条件的元组(记录);


例如,Sname=“zhuguozhu”,并且Sname上定义了索引,则可以使用索引得到Sname为“zhuguozhu”的元组的指针,然后通过这个指针在student表中查找到该学生相关信息。

---------------

例如,Sage>30,并且Sage定义B+树索引,可以直接使用B+树索引找到Sage=30索引项,以该索引项为入口,访问B+树顺序集,进而得到Sage>30所有元组指针,最后通过这些指针在student表中查找到所有年龄大于30的学生信息。

---------------

例如Sname=’zhuguozhu’ and Sage>20,假设student表中对Sname和Sage都定义索引。

该选择操作执行有两种算法,

(1)分别找到Sname=’zhuguozhu’的一组元组指针和Sage>20的元组指针,求这两组元组指针的交集,再在student表中根据两组元组指针的交集进行检索,就可以得到年龄大于20,并且姓“zhuguozhu”的学生信息。

(2)先求出Sname=’zhuguozhu’指针,通过这组指针在student表中检索,在得到的元组集合中再检查另外一个选择条件Sage>20是否满足,把满足条件的元组作为结果输出。


(2)连接操作实现算法

连接操作是查询处理中最耗时操作

a. 等值连接(或自然连接)b. 嵌套循环算法c. 排序合并算法d. 索引连接算法


e.g.:

select * from student , sc where student.sno = sc.sno;
  1. 嵌套循环算法:简单可行方法,使用两层循环进行查询。对外层循环表(对应基表student)的每一个元组(记录),检索内层循环表(对应基表sc)中的每一个元组(记录),检查这两个元组连接属性(sno)上是否相等。如相等,则把这两个元组串在一起作为查询结果输出,直到外层循环表元组都处理完为止。

实现简单,适用于小表,如大表,则循环检索的时间长,检索效率低;

假设student表有1000条学生记录,每个学生选修10门课程,那么sc表中将有10000条记录。

如采用嵌套循环方法,学生表只需要检1次即可,但是sc表却要检索1000次,每一次都要把它的10000条记录到检索一遍,总共需要检索10000*1000=10000000条元组,时间代价比较高,检索效率较低。


  1. 排序-合并算法:适合连接待连接表已经安装连接属性排序序的情况;

a. 对待连接表按照连接属性进行排序(如已排序则省略此步骤),连接首先是对student表和sc表安装连接属性sno进行排序;

b. 首先去student表第一个sno, 然后依次检索sc表中,只要检索到具有相同sno的元组,就进行元组串联;

c. 当在sc表中检索到sno不同的第一个sc元组时,就需要返回student表,扫描下一个元组,再回到sc表中扫描和新的sno相同的元组,把它们串联起来

d. 重复b, c步骤,直到整个student表检索完毕;

/////////////////////////////////////////////////

该方法好处是连接的两个表student和sc只需要检索一遍即可,大大节省了检索所花费的时间。

如果两个表开始并未排序,那么整个连接所花费的时间还需要加上排序时间,但是对于大表而言,先排序再使用排序-合并算法进行连接会大大的减少执行的时间。

例如:student中有1000条记录,每个学生10们课,sc表中有10000条记录,连接所需要检索的次数为1000*10 = 10000条,跟前面的10000000相比,时间减少很多。


  1. 索引连接算法:建立在索引基础上的一种连接方法;

a. 在sc表中建立属性sno的索引,如果原表已经建立,则省略此步骤

b. 对student表中的每一元组,根据sno的值通过sc表的索引来查找对应的元组记录;

c. 把找到的sc表中的元组和student的元组连接起来;

d.  循环执行b c步骤,直到student表检索完毕。

///////////////////////////////////////////////////////////////////////////

该方法非常适用于大表,连接所花费的时间非常少,基本不用扫描不满足条件的元组记录。



2.关系数据库系统查询优化

先对用户所给的语句进行转换,将其转换为一串执行时间较少的关系代数表达式(代数优化),并为这些运算选择较优的存取路径(物理优化),以便能大大减少执行时间;

查询的执行开销=I/O代价+CPU代价+内存代价+通信代价

在关系代数代数运算中:笛卡尔积、连接运算是最费时间和空间的;

关系代数表达式的优化准则:

a. 尽早进行选择运算;b. 同时进行投影运算和选择运算;c. 把投影运算同其前或其后的双目运算结合起来;d. 合并笛卡尔积与其后的选择运算为连接运算;e. 存储公共子表达式;


2.1关系代数表达式的优化算法

算法:关系代数表达式的优化;

输入:一个关系表达式的查询树;

输出:优化后的查询树;

2.2物理优的优化算法

(1)启发式规则优化

(2)代价估算的优化

基于代价优化方法,优化器对查询各种执行策略进行代价估算,这时就要数据库中数据字典中所存储的一些统计信息(mysql的统计信息是存储在InnoDB中)进行辅助。

3)(1)+(2)相结合的优化--》首先会基于启发式规则优化,从多种执行策略中选择若干较优候选策略,从而减少代价估算工作量,然后再用基于代价估算的优化算法,分别估算出这些候选策略执行代价,进而较快的选出最终的优化策略



3.小结:

实际的数据库系统--》综合使用了各种技术,所以【优化器】是比较复杂的;


以上是关于数据库查询处理及优化的主要内容,如果未能解决你的问题,请参考以下文章

你如何在 python 中处理 graphql 查询和片段?

Django进阶之查询优化extra注入SQL及批量创建

Mysql优化系列之——优化器对子查询的处理

15种Python片段去优化你的数据科学管道

浅谈 SQL Server 查询优化与事务处理

Oracle数据库查询优化方案(处理上百万级记录如何提高处理查询速度)