如何使用 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 运算符?的主要内容,如果未能解决你的问题,请参考以下文章
db2中left()函数和right()函数对应oracle中的substr()函数
db2中left()函数和right()函数对应oracle中的substr()函数