近日,针对集中式国产数据库的SQL能力,个人做了简单测试并发了总结稿。这一结果也得到了众多国内数据库厂商的响应,一方面国产数据库还在快速迭代更新之中,有些能力会在不久的将来具备;另一方面受个人对国产数据库理解及数据库反馈内容的局限,有些能力其实已经具备但未表现出来。本篇就是针对达梦数据库的一轮复测,重点是放在此前表述为不支持的能力上。下文针对重点操作打了星号,并在下文给出了示例。这里,特别感谢达梦数据库对此次测试的支持。
1. 测试内容:访问路径
针对索引的单值查询,达梦数据库实际走的也是索引唯一扫描,不同的是操作符都是SSEK,可根据扫描范围scan_range属性来判断是否范围还是单值定位,如下图一。对于带有DISTINCT的查询,则会使用DSSEK操作符,扫描到第一个KEY,会跳过重复值就直接找到下一个KEY,如下图二。
针对索引快速全扫描,达梦数据库与Oracle的实现不同,它可通过多入口(并行的方式),是对索引的并行访问,进而提高索引访问速度。至于是否按照多块读取的方式,则是具体根据扫描时的情况来判断,达梦只能提供参数multi page get,即这个是每次获取多个块来配置实现。
针对索引跳跃扫描,达梦数据库并不是一个操作符完成,而是通过 NLIJ+CONSTC+SSEK 组合完成。下图中是针对两个列创建的复合索引,然后根据索引第二列进行查询的情况。关键字CONSTC明确指出其采用了复合索引的跳跃扫描。
2. 测试内容:连接方式
在内连接方面,达梦数据库支持了标准的NL、SM、HJ。下图一为嵌套循环示例,下图二为合并排序示例。
在半连接方面,达梦数据库支持了多种实现方式,包括HJ、SM等。
在反连接上,达梦数据库会转换为半连接方式处理,也会使用到HJ、SM等;但对于Null Aware的连接,还存在不足,尚不支持单独算子,如下图三。
3. 测试内容:子查询优化
3.png
针对子查询推入,先来回顾下其含义。子查询推入,是一项对未能合并或者反嵌套的子查询优化的补充优化技术。通常情况下,未能合并或者反嵌套的子查询的子计划会被放置在整个查询计划的最后步骤执行,而子查询推进使得子查询能够提前被评估,使之可以出现在整体执行计划的较早步骤,从而获得更优的执行计划。在如下图示例中,主查询过滤时,是将子查询结果集被推入到主查询,主查询得到提前过滤。
针对简单谓词推入,先回顾下其含义。简单地将主查询中作用于子查询的过滤谓词推入子查询中。它是属于启发式查询转换技术,只要满足条件就会进行转换。在下图示例中,主查询的过滤谓词被推入到子查询之中。
4. 测试内容:排序去重与分组聚合
对于排序合并中,达梦数据库针对去重使用DISTINCT操作符完成,内部实现也是基于HASH UNIQUE,如下图一。针对排序去重场景,则使用了SORT3实现排序,并在过程中实现去重。
针对排序聚合场景,没有索引和有索引的情况分别对应使用AAGR2和FAGR2的操作符,支持这两种情况。
针对一般排序的STOP KEY的情况,则使用SORT+TOP_FLAG的方式来实现。
在排序关联中,达梦数据库利用嵌套循环+索引有序性,来保证结果集有序。
在分组+排序场景,如果没有索引,则使用HAGR+SORT的方式来实现SORT GROUP BY,如下图一;如果有索引则直接使用SAGR。