如何用外部程序优化SQL语句中的IN和EXISTS(3)

我们先来看一下 LINEITEM 表的数据特点,LINEITEM 表的主键是 L_ORDERKEY、L_LINENUMBER,一个订单对应 LINEITEM 里的多条记录,这些记录的 L_ORDERKEY 是相同的并且在数据文件中是相邻的。知道这些信息后再来分析上面的 SQL,其条件是为了找出有多个供应商供货并且有且仅有一个供应商没有按时交货的订单,因为数据是按订单顺序存放的,这样我们就可以按订单有序分组,然后循环每组订单判断是否有没按时交货的订单项,是否有多个供货商,并且是不是只有一个供应商没有按时交货。

集算器实现:

如何用外部程序优化SQL语句中的IN和EXISTS

总结

在没有空值的时候带子查询的 IN 都可以用 EXISTS 描述,同一个查询需求用 IN 描述和用 EXISTS 描述翻译成的集算器代码是相同的,所以我们只要弄清楚 EXISTS 怎么翻译和优化就知道 IN 怎么处理了。

等值 exist 本质上是做连接,两个表做连接效率较好的两种方式是哈希连接和有序归并连接,对于翻译 select *** from A where exists (select *** from B where ***) 样式的 SQL,我们首先要弄清楚下列信息:

(1)关联字段是否是各表的主键或者逻辑主键

(2)A、B 表的规模,执行其它过滤条件后是否能载入内存

(3)如果没有某个表能装入内存则要考察两个表是否按关联字段有序

如果有一个表能载入内存则可以选用哈希连接的方式来实现,相关的集算器函数有两个 cs.switch()、cs.join(),这两个函数有两个可用的选项 @i、@d 分别对应 exists 和 not exists,参数里的表要求按关联字段值唯一,如果不是逻辑主键则要先去重,可用 A.groups()去重。如果两个表都很大不能载入内存则要考察两个表是否按关联字段有序,如果无序可以用 cs.sortx() 排序,对于有序的两个表就可以用 joinx() 来做连接了。

非等值运算则要分析其中的运算逻辑看能否转成分组后再计算,如果不能则只能使用嵌套循环连接的方式了,对应的函数是 xjoin()。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/4d3574aff845142d9e47ec19ff234e94.html