目录
- 前言
- 查询执行过程
- 单表选择操作常用算法
- 连接操作的实现算法
- 基于关系代数优化
- 总结
前言
对于一个只有几千行甚至几万行数据的查询的小系统来说,数据库的查询优化作用不大,但对于大型的应用系统,数据动辄上百万,就需要了解DBMS对查询语句的处理过程和优化算法,更好的利用其优化算法,以提高系统的性能。
查询执行过程
执行一条查询语句需要做查询分析、查询检查、查询优化、查询执行等几个关键步骤,具体描述如下:
查询分析:对查询语句进行扫描、词法分析和语法分析,从查询语句中识别出语言符号,进行语法检查和语法分析
查询检查:根据数据字典对合法的查询语句进行语义检查。包括对用户的存取权限进行检查和完整性约束定义检查;检查通过后把SQL查询语句转换成等价的关系代数表达式,一般都用查询树(语法分析树)来表示关系代数表达式
查询优化:数据库管理系统会自动的选择一个高效执行的查询处理策略。所谓的查询优化就是我们DBMS可选择的高效查询处理策略,提供条件,如:建立那种类型的索引
查询执行:代码生成器(code generator)生成执行查询计划的代码,执行相应指令。 查询优化是根据DBMS根据物理设计建立的存取路径,选择最优的算法进行优化,DBMS查询优化包括代数优化和物理优化。
单表选择操作常用算法
- 全表扫描:对查询的基本表顺序扫描,逐一检查每个元组是否满足选择条件,把满足条件的元组作为结果输出。此种算法适合小表,不适合大表
- 索引扫描:通过索引先找到满足条件的元组主码或元组指针,再通过元组指针直接在查询的基本表中找到元组,索引使用B+树或hash散列,当元组比较多时,速度比全表扫描快
在选择操作上的启发
结论:使用全表扫描还是索引扫描,是由DBMS根据表中记录数多少和查找数据记录数进行选择的。
一般情况下是选择的记录数大于整个表记录总数的20%或者表中的记录很少,使用全表扫描。因此如果表中记录很少或者每次查询选用的记录很多,所建的索引不能提高性能。
连接操作的实现算法
以 SELECT * FROM student,sc WHERE student.sno=sc.sno为例,假设student表中1000条记录,sc表中10000条记录
在连接操作上的启发
- 如果2个表都已经按照连接属性排序,选用排序-合并方法
- 如果一个表在连接属性上有索引,选用索引连接方法
- 如果上面2个规则都不适用,其中一个表较小,选用Hashjoin方法
- 可以选用嵌套循环方法,并选择其中较小的表,确切地讲是占用的块数(b)较少的表,作为外表(外循环的表)
结论: 当表中的元祖数比较大时,建议建立索引,这样会大大的提高查找效率。但需要执行索引查找需要通过索引的指针间接地获取数据以及管理索引也需要成本,当元祖数少的时候,DBMS不会选择排序合并和索引连接。当一个表元祖少,一个多,无索引时,DBMS可能会选择Hash连接
基于关系代数优化
集中式数据库:总代价=I/O代价+CPU代价+内存代价,主要考虑I/O代价;
分布式数据库:总代价=I/O代价+CPU代价+内存代价+通信代价,主要考虑I/O代价和通讯代价
【示例】: 假定学生-课程数据库中有1000个学生记录,10000个选课记录,其中选修2号课程的选课记录为50个,使用不同关系代数计算此SQL表达式的代价 SELECT Student.Sname FROM Student,SC WHERE Student.Sno=SC.Sno AND SC.Cno=‘2’; 设一个块能装10个Student元组或100个SC元组,在内存中可以存放5块Student元组和1块SC元组。
代数优化启发,尽量减少I/O操作,减少写入读入数据块的次数,就可以提高性能,对我们有以下启发
- 选择运算应尽可能先做。在优化策略中这是最重要、最基本的一条
- 把投影运算和选择运算同时进行,减少读写中间文件次数
- 把投影同其前或其后的双目运算结合起来
- 减少扫描关系的次数
- 某些选择同在它前面要执行的笛卡尔积结合起来成为一个连接运算
- 找出公共子表达式
总结
查询优化技术是每中类型的数据库管理系统中的关键技术,是由DBMS自动完成的,但不要把优化的任务全部放在RDBMS上,应该找出RDBMS的优化规律,以写出适合RDBMS自动优化的SQL语句。 对于RDBMS不能优化的查询需要重新规划书写查询语句,进行手工调整以优化查询性能。
到此这篇关于数据库sql查询性能优化详解的文章就介绍到这了,更多相关数据库查询优化内容请搜索悠久资源以前的文章或继续浏览下面的相关文章希望大家以后多多支持悠久资源!