如何使用 substr 避免 DB2 Blu 中的 CTQ 运算符?

Posted

技术标签:

【中文标题】如何使用 substr 避免 DB2 Blu 中的 CTQ 运算符?【英文标题】:How to avoid CTQ operator in DB2 Blu with substr? 【发布时间】:2020-02-20 12:53:20 【问题描述】:

我正在使用 DB2 Blu,由于 CTQ 运算符不够高,因此我在使用 SUBSTR 的查询计划中经常遇到问题。

这是一个例子:

select
coalesce(annee,annee_semaine),
count(JOUR_OUVRE)
from d_tps_calendrier
group by grouping sets((annee),(annee_semaine))

查询计划没问题:

Rows 
            RETURN
            (   1)
             Cost 
              I/O 
              |
             2701 
            L   TQ
            (   2)
            334.257 
              224 
              |
             2701 
              C TQ
            (   3)
            333.573 
              224 
              |
             2701 
            UNION 
            (   4)
            332.721 
              224 
            /-+--\
         2649      52 
        GRPBY    GRPBY 
        (   5)   (  10)
        166.197  166.107 
          112      112 
          |        |
         22310    22310 
        TBSCAN   TBSCAN
        (   6)   (  11)
        165.176  165.176 
          112      112 
          |        |
         22310    22310 
        TEMP     TEMP  
        (   7)   (   7)
        147.121  147.121 
          112      112 
          |
         22310 
        GRPBY 
        (   8)
        134.404 
          112 
          |
         22310 
        TBSCAN
        (   9)
        132.702 
          112 
          |
         22310 
  CO-TABLE: INFIFZ00
 D_TPS_CALENDRIER_INF
          Q1

现在,我真正想做的是用 annee_semaine 的前 3 个字符分组:

select
coalesce(annee,substr(annee_semaine,1,3)),
count(JOUR_OUVRE)
from d_tps_calendrier
group by grouping sets((annee),(substr(annee_semaine,1,3)))

现在在查询计划中,group by 和 union 是在 CTQ 运算符之后完成的

Rows 
            RETURN
            (   1)
             Cost 
              I/O 
              |
             2701 
            UNION 
            (   2)
            431.235 
              224 
            /-+--\
         2649      52 
        GRPBY    GRPBY 
        (   3)   (  14)
        220.453  210.366 
          112      112 
          |        |
         2649     22310 
        TBSCAN   TBSCAN
        (   4)   (  15)
        220.219  208.372 
          112      112 
          |        |
         2649     22310 
        SORT     TEMP  
        (   5)   (   7)
        220.219  190.317 
          112      112 
          |
         22310 
        TBSCAN
        (   6)
        208.372 
          112 
          |
         22310 
        TEMP  
        (   7)
        190.317 
          112 
          |
         22310 
        LM  TQ
        (   8)
        181.039 
          112 
          |
         22310 
        GRPBY 
        (   9)
        165.712 
          112 
          |
         22310 
        TBSCAN
        (  10)
        163.749 
          112 
          |
         22310 
        SORT  
        (  11)
        161.817 
          112 
          |
         22310 
          C TQ
        (  12)
        132.866 
          112 
          |
         22310 
        TBSCAN
        (  13)
        132.702 
          112 
          |
         22310 
  CO-TABLE: INFIFZ00
 D_TPS_CALENDRIER_INF
          Q1

我尝试使用 left 而不是 substr,但没有成功。在 DB2 Blu 中处理 substr 有什么好的做法吗?

在其他情况下,我可以直接将 de substr 放在表格的一列中,但在这种情况下是不可能的。

【问题讨论】:

完整地说,第二个查询计划是使用 SUBSTRING 而不是 SUBSTR。在这个简化的示例中,使用 SUBSTR 查询计划是可以的,但在实际更复杂的查询中,即使使用 SUBSTR 也不是。 什么版本的 Db2?每个模组包和新版本都有改进 信息性标记是“DB2 v11.1.4.4”、“s1902261400”、“DYN1902261400AIX”和 Fix Pack “4a”。 【参考方案1】:

这成功了:

select
coalesce(annee,cast(annee_semaine as vargraphic(3))),
count(JOUR_OUVRE)
from d_tps_calendrier
group by grouping sets((annee),(cast(annee_semaine as vargraphic(3))))

它并不完美,因为它只适用于我想要第一个字符而不是 substr(str,4,5) 之类的东西

【讨论】:

【参考方案2】:

一种选择是向始终生成的表中添加一列,例如:

annee_semaine3 char(3) generated always as (substring(annee_semaine,1,3)) implicitly hidden

然后您可以按此隐藏列进行分组。

select
coalesce(annee,substr(annee_semaine,1,3)),
count(JOUR_OUVRE)
from d_tps_calendrier
group by grouping sets((annee),(annee_semaine3))

您也可以在 select 子句中显式引用它来避免这种计算。

由于该列是隐藏的,像select *这样的操作不会包含它;必须明确命名。

【讨论】:

即使在 11.5 中,也无法将生成的列添加到现有的按列组织的表中。必须使用这样的生成列重新创建和重新加载表。 我会记住这个方法,但现在我会避免重新加载表,因为它在多个模式中使用

以上是关于如何使用 substr 避免 DB2 Blu 中的 CTQ 运算符?的主要内容,如果未能解决你的问题,请参考以下文章

REGEXP_SUBSTR - 如何“避免”字符串中的括号

db2中left()函数和right()函数对应oracle中的substr()函数

db2中left()函数和right()函数对应oracle中的substr()函数

我们应该在检索数据时避免 DB2 SQL 中的 IN 子句吗?

hive substring 空格怎么算

DB2中的正确更新语句,以避免事务日志已满