一、执行计划定义
达梦数据库(DM8)的执行计划是数据库优化器生成的用于执行SQL语句的步骤序列,它描述了数据库系统将如何访问和处理数据以完成查询请求。
二、执行计划相关核心概念
1、查询优化器
查询优化器是数据库管理系统的核心组件,负责将用户提交的SQL查询转换为高效执行计划。以下是关于查询优化器的详细介绍:
查询优化器的主要功能如下:
查询重写:对原始SQL进行语法和语义的等价转换
执行计划生成:探索可能的执行路径
成本估算:基于统计信息评估每个计划的执行代价
最优计划选择:选择预估成本最低的执行方案
2、访问路径
数据库访问路径是指数据库系统在执行查询时访问数据的具体方式,它决定了数据如何从存储介质中被检索出来。
数据库优化器在选择访问路径时会考虑以下因素:
统计信息: 表大小、数据分布、索引选择性等
查询条件: WHERE子句中的条件
连接方式: 表连接的方法和顺序
系统资源: 内存、I/O能力等
提示(Hints): 开发人员指定的访问路径提示
3、成本
数据库优化器估算的执行特定SQL语句所需的资源消耗,DM8数据库查询优化器默认是基于成本的优化 Cost-Based Optimizer (CBO)
三、常见执行计划举例说明
采用DM8示例库 DMHR模式下的部分表, 这些表可以在DM8官方下载并导入数据库
1、全表扫描
EXPLAIN SELECT * from DMHR.EMPLOYEE;
CSCN2: Cluster Index Scan 的缩写,即扫描聚集索引,由于DM8中表的物理组织方式为索引组织表(IOT),所以扫描聚集索引即对全表的扫描,由于该sql没有谓词(where条件),所以系统只能通过全表扫描获取表中的数据,这种方式一般对系统性能影响较大,一般情况需要尽量避免。
附加信息中的INDEX33555477(EMPLOYEE) 为 <索引名>(表名)
PRJT2: 关系的投影,一般用于表达式项的计算
NSET2:结果集收集,一般卫浴查询计算的顶层节点
2、索引范围扫描
explain SELECT * from DMHR.EMPLOYEE where PHONE_NUM='15312348552';
SSEK2: 二级索引数据定位,附加信息为扫描类型(ASC), <索引名>(表名)
BLKUP2: 二次定位查找,即回表 , 附加信息为<索引名>(表名)
3、索引全扫描
explain select * from dmhr.job where job_id=21;
SSCN: 索引全扫描,不需要扫描表
4、嵌套循环
表创建和数据导入:
CREATE TABLE Products
(name VARCHAR(16) PRIMARY KEY,
price INTEGER NOT NULL);
--可重排列·排列·组合
INSERT INTO Products VALUES('苹果', 50);
INSERT INTO Products VALUES('橘子', 100);
INSERT INTO Products VALUES('香蕉', 80);
explain select p1.name as name_1,p2.name as name_2
from products p1,products p2
where p1.name<>p2.name;
NEST LOOP INNER JOIN2: 嵌套循环内连接,另外相关操作符如下:
NEST LOOP INDEX JOIN2: 嵌套循环全外连接
NEST LOOP FULL JOIN2: 索引内连接
NEST LOOP LEFT JOIN2: 嵌套循环左外连接
本示例利用表的自联结,生成有序对(排列),表的不等值自联结过程利用了嵌套循环连接算法,即选择一个驱动表(外层循环),扫描外层驱动表,使得外层驱动表的每一行与内层表的逐行匹配
5、哈希连接
沿用上例数据
explain select p1.name as name_1,p2.name as name_2
from products p1,products p2
where p1.name=p2.name;
HASH2 INNER JOIN: HASH内连接
Hash Join 通过使用哈希表(hash table)数据结构来提高连接操作的效率,其基本思想是:
对较小的表(通常称为构建表/build table)构建内存中的哈希表
然后扫描较大的表(探测表/probe table),并对每条记录应用相同的哈希函数,查找哈希表中匹配的记录
hash join相关参数如下:
HJ_BUF_GLOBAL_SIZE
HASH 连接操作符的数据总缓存大小 ()>=HJ_BUF_SIZE),系统级参数,以兆为单位。有效值范围(10~500000) SYS
HJ_BUF_SIZE 单个哈希连接操作符的数据总缓存大小,以兆为单位。有效值范围(2~100000) SESSION
HJ_BLK_SIZE 哈希连接操作符每次分配缓存( BLK )大小,以兆为单位,必须小于 HJ_BUF_SIZE。有效值范围(1~50) SESSION
6、INDEX JOIN
explain
select distinct A.student_id from testscores A
where not exists
(select * from testscores B
where
(subject='数学' and score<80
or subject='语文' and score<50)
and
A.Student_Id=B.student_id
)
INDEX JOIN SEMI JOIN: 索引半连接
附加信息:
flt_batch_exec标记:节点上是否存在filter的批量指令,存在则为flt_batch_exec(1),否则为flt_batch_exec(0)
索引半连接相关解释:
半连接(Semi Join):只返回左表中与右表匹配的记录,且每个左表记录只返回一次(不重复),不返回右表的任何字段。
索引半连接:在执行半连接时利用索引来加速匹配过程的一种优化方式。工作原理如下:
数据库优化器选择一个驱动表(通常是较小的表或筛选条件更严格的表)
使用索引快速定位驱动表中的相关行
对于驱动表中的每一行,使用被驱动表上的索引快速检查匹配是否存在
只返回驱动表中存在匹配的行
这种连接方式特别适合以下查询:
使用EXISTS的子查询
使用IN的子查询(当优化器将其转换为半连接时)
需要检查关联表中是否存在匹配记录但不需返回关联表数据的查询
7、综合示例
相关数据:
CREATE TABLE Sales
(year INTEGER NOT NULL ,
sale INTEGER NOT NULL ,
PRIMARY KEY (year));
INSERT INTO Sales VALUES (1990, 50);
INSERT INTO Sales VALUES (1991, 51);
INSERT INTO Sales VALUES (1992, 52);
INSERT INTO Sales VALUES (1993, 52);
INSERT INTO Sales VALUES (1994, 50);
INSERT INTO Sales VALUES (1995, 50);
INSERT INTO Sales VALUES (1996, 49);
INSERT INTO Sales VALUES (1997, 55);
EXPLAIN SELECT year,sale
FROM Sales S1
WHERE sale = (SELECT sale
FROM Sales S2
WHERE S2.year = S1.year - 1)
ORDER BY year;
注:本sql要求求出以下结果集:求与上一年营业额一样的年份,该示例使用了关联子查询
HAGR2: HASH分组,并计算集函数
SORT3: 排序
文章
阅读量
获赞