论文部分内容阅读
随着信息化的普及,信息系统覆盖到各行各业,而根据实际业务的需求,数据库的查询方式越来越复杂。
子查询在数据库复杂查询中的使用频率较高,且子查询的性能会直接影响到业务处理的效率。如果数据库内部可以对子查询进行优化处理,大有好处:一方面可以大大减少技术人员的工作量,另一方面还能降低SQL语句的复杂度。达梦DM7对子查询进行了大量优化处理,提升了子查询的性能,进而提升业务处理的效率。
选择极优连接方式
相关子查询可以转换为四种半连接:哈希半连接、索引半连接、嵌套半连接、归并半连接。(注:本文对子查询的描述使用术语内表和外表。在子查询内出现的表称之为内表;只在子查询之外出现的表称之为外表。)
相关子查询优化处理最后阶段会选择极优的连接方式。选择连接方式时,首先根据连接条件确定采用何种连接方式,等值连接条件会选择哈希\索引\归并半连接,非等值连接条件会选择嵌套半连接;然后,对各种连接方式根据代价算法进行代价计算;最后,比较各种连接方式的代价,以此为依据,选择代价最小的连接方式,作为最终执行计划的连接方式。
哈希半连接、索引半连接、归并半连接和嵌套半连接,这四种不同半连接的特性分别如下:
一、哈希半连接。哈希半连接是以左表的连接列为key构造哈希表,右表的连接列进行探测来查找满足连接条件的记录。
二、索引半连接。如果子查询的连接列为索引前导列,则可以转换相关子查询为索引半连接方式处理。处理过程为外表的数据对子查询使用索引查找,满足条件的记录返回。
三、归并半连接。如果相关子查询的连接条件列均为索引列,则可采用归并半连接来实现。按照索引顺序,对外表、内表进行同步扫描,选择满足连接条件的记录,再根据过滤条件进行过滤得到最终结果,经过一趟归并即可完成。
四、嵌套半连接。如果连接条件为非等值,则可转换为嵌套半连接方式处理。处理过程为外部表的单条记录去遍历内表,满足条件的记录返回。
除此之外,还包括一些优化,例如相关子查询可以转换为哈希左半连接和哈希右半连接。其中,当子查询的代价小于外表时,会采用哈希右半连接处理。处理过程类似哈希左半连接。
优化前后处理方式对比
DM7相关子查询的优化机制基于多种半连接方式和优化机制,覆盖了较多的可优化场景,极大地减少了应用开发人员对SQL语句等价改写的工作量。此优化机制在各种测试中均取得较好的效果,与优化前相比在性能上有数量级的提升。
下面对优化前后的不同处理方式进行对比:
优化前:以外表驱动,从外表每取一条记录,遍历一遍内表,按照过滤条件判断是否满足,如果满足则输出,否则不处理。相当于内表和外表做了一次笛卡尔集,在大数据量情况下,执行效率非常低。例如,两张60万的数据表执行子查询,笛卡尔集会产生3600亿条记录,对这3600亿条记录进行过滤,计算量和I/O量都是巨大的,执行时间长。这是无法让用户接受的。
优化后:对于相关子查询的优化思想是转换为半连接进行处理。执行过程为:读取外表的一批数据;把满足连接条件的记录打上标记;处理完本批数据,返回有标记(in/exists)或无标记(not in/not exists)的记录;循环处理步骤1到步骤3,直到外表数据处理完。
子查询在数据库复杂查询中的使用频率较高,且子查询的性能会直接影响到业务处理的效率。如果数据库内部可以对子查询进行优化处理,大有好处:一方面可以大大减少技术人员的工作量,另一方面还能降低SQL语句的复杂度。达梦DM7对子查询进行了大量优化处理,提升了子查询的性能,进而提升业务处理的效率。
选择极优连接方式
相关子查询可以转换为四种半连接:哈希半连接、索引半连接、嵌套半连接、归并半连接。(注:本文对子查询的描述使用术语内表和外表。在子查询内出现的表称之为内表;只在子查询之外出现的表称之为外表。)
相关子查询优化处理最后阶段会选择极优的连接方式。选择连接方式时,首先根据连接条件确定采用何种连接方式,等值连接条件会选择哈希\索引\归并半连接,非等值连接条件会选择嵌套半连接;然后,对各种连接方式根据代价算法进行代价计算;最后,比较各种连接方式的代价,以此为依据,选择代价最小的连接方式,作为最终执行计划的连接方式。
哈希半连接、索引半连接、归并半连接和嵌套半连接,这四种不同半连接的特性分别如下:
一、哈希半连接。哈希半连接是以左表的连接列为key构造哈希表,右表的连接列进行探测来查找满足连接条件的记录。
二、索引半连接。如果子查询的连接列为索引前导列,则可以转换相关子查询为索引半连接方式处理。处理过程为外表的数据对子查询使用索引查找,满足条件的记录返回。
三、归并半连接。如果相关子查询的连接条件列均为索引列,则可采用归并半连接来实现。按照索引顺序,对外表、内表进行同步扫描,选择满足连接条件的记录,再根据过滤条件进行过滤得到最终结果,经过一趟归并即可完成。
四、嵌套半连接。如果连接条件为非等值,则可转换为嵌套半连接方式处理。处理过程为外部表的单条记录去遍历内表,满足条件的记录返回。
除此之外,还包括一些优化,例如相关子查询可以转换为哈希左半连接和哈希右半连接。其中,当子查询的代价小于外表时,会采用哈希右半连接处理。处理过程类似哈希左半连接。
优化前后处理方式对比
DM7相关子查询的优化机制基于多种半连接方式和优化机制,覆盖了较多的可优化场景,极大地减少了应用开发人员对SQL语句等价改写的工作量。此优化机制在各种测试中均取得较好的效果,与优化前相比在性能上有数量级的提升。
下面对优化前后的不同处理方式进行对比:
优化前:以外表驱动,从外表每取一条记录,遍历一遍内表,按照过滤条件判断是否满足,如果满足则输出,否则不处理。相当于内表和外表做了一次笛卡尔集,在大数据量情况下,执行效率非常低。例如,两张60万的数据表执行子查询,笛卡尔集会产生3600亿条记录,对这3600亿条记录进行过滤,计算量和I/O量都是巨大的,执行时间长。这是无法让用户接受的。
优化后:对于相关子查询的优化思想是转换为半连接进行处理。执行过程为:读取外表的一批数据;把满足连接条件的记录打上标记;处理完本批数据,返回有标记(in/exists)或无标记(not in/not exists)的记录;循环处理步骤1到步骤3,直到外表数据处理完。