在前两期的分享中,我们介绍了在做单表及多表查询时用到的SQL操作符。本次,我们就来讲一讲过滤和分组排序时用到的操作符。
过滤条件:SLCT
这类操作符比较简单,是对结果集进行过滤,需要注意的是操作符的描述信息,从描述信息中我们可以看到对于下层操作有哪些可用的过滤条件,这些条件往往是优化方向的来源。
需要关注的是SLCT 的描述部分 (exp_cast(T2.ID) > 5 AND exp11 <= 0),这里括号中的内容将ID > 5 标注为了EXP_CAST(T2.ID)> 5,ID NOT LIKE '%c%'标注为了 EXP11 <= 0。其中EXP_CAST(T2.ID)> 5 提供的信息告诉我们,列ID 和数字5进行比较,是要将列作类型转换的,那么也就是说,就算ID列上存在索引,可能也不能进行范围扫描,因为索引范围扫描的输入要求是和索引列上的类型相同,我们验证一下
确实,在存在索引( create indexi_index3 on t2(id))的情况下,单列等值查询也没有走索引进行查询,这个在此也只说明一个大致原理,不同类型数据进行比较时会先选取一种比较类型,再确定比较方法。比如在此例中,比较 ID(VARCHAR)= 5(INT),服务器优先选择把类型转换成INT 进行比较,所以导致ID列需要做类型转换,从而不能利用索引(没有索引存储了转换之后的数据)。碰到这种情况,我们需要把索引列的对比对象转换为和索引列一样的格式
另外一个条件ID NOT LIKE '%c%',转换为EXP11 <= 0 ,实际上是把NOT LIKE 转换成了 INSTR(ID,'c') <= 0, 原理在此暂不多赘述,我们希望做到的是
对于SLCT描述项中的每一个,都能在原始SQL中找到对应的条件,并看下是否存在优化的可能性
分组:HAGR,SAGR
这类操作符都是对取到的数据做一些处理,或归并,或排序,而归并和排序在某些情况下是互通的我们先看这些操作符出现的基本情况。存在GROUP 的语句,大概率会出现这两个之一
SQL> create table t4(id int,id1varchar);
SQL> insert into t4 select level,levelfrom dual connect by level < 10000;
SQL> commit;
HAGR是最基础的分组方式,HASH AGR操作,对于没有优化条件的分组语句,一般都会按这种方式进行分组,分组原理和HASH INNER JOIN 的方式类似,将原表数据取出,每个计算FOLD,发现有FOLD相同,且满足后续条件的合并为一组(,不难发现,如果基表数据非常庞大时,HAGR的计算量是不容忽视的,那么满足一定条件的情况下,我们可以利用有序性走SAGR操作符
SQL> create or replace index i_test4 ont4(id,id1);
这里出现SAGR操作符,说明下层的输出是按分组列排序的,下层为SSCN I_TEST4,而I_TEST4为(ID,ID1)组合索引,按照ID有序,满足SAGR条件
SAGR, SORTED AGR操作,不同于HASH AGR,由于下层数据有序,同一分组的数据按照顺序取出就行,节省了大量的计算
排序:SORT:
SORT是做排序操作时使用到的操作符,我们可以进行如下实验。
可以看到,这里并没有出现SORT操作符。如前文所说,索引I_TEST已经是以ID有序的了,所以在下层的SSCN中已经把排序的任务做完了。如果我们换一列来测试。
SQL> explain select id,id1 from t4order by id1 desc;
如果是对id1列进行排序,则在SSCN之后,还需要针对id1做一次SORT,这对数据库也是一笔不小的开销。所以在实际运用中,我们也可以想办法利用索引的有序性来完成排序的操作。
达梦SQL优化的基础篇,关于操作符的介绍就到这里了。在后续的分享中,我们还会为大家介绍执行计划的查看以及索引方面的知识,敬请期待!
【干货分享】达梦SQL优化——基础篇
【干货分享】达梦SQL优化——基础篇(2)