我正在尝试查询一个表,并根据另一个包含include和exclude条件的表从中获取一些值。
我有这样的主表:
ColA
600000
675100
123000
标准表如下:
Value | Type
6% | I
67% | E
其中%
充当外卡。
结果表应为:
ColA
600000
我已经让它得到了正确的结果:
select *
from main
inner join criteria inc
on ColA like inc.value
and inc.type = 'I'
left outer join criteria exc
on ColA like exc.value
and exc.type = 'E'
where exc.value is null
;
但是我希望我能在不必查询条件表两次的情况下得到它,因为在创建它时会涉及一些计算。
我想这只是一个可能的性能提升问题,但我认为要求社区没有害处!
谢谢大家!
修改
正如评论中所提到的,我设法将条件表纳入范围。我使用此查询完成了(期望10位数字):
select case
when type = 'I'
then low
when type = 'E'
then low_1
end as low,
case
when lead(type) over (order by low asc) = 'E'
then case
when type = 'I' and high < lead(low) over (order by low asc)
then high
else lead(high_1) over (order by low asc) end
when type = 'I'
then high
else
max_high
end as high
from (
select *,
rpad(digits,10,9) as high,
rpad(digits+1,10,0) as low_1,
rpad(digits-1,10,9) as high_1
from (
select main.*,
max( for_max_high ) as max_high
from (
select type,
replace(value,'%','') as digits,
rpad(replace(value,'%',''),10,0) as low
from criteria
) main
left outer join (
select replace(value,'%','') as digits,
rpad(replace(value,'%',''),10,9) as for_max_high
from criteria
where type = 'I'
) for_max
on main.low > rpad(for_max.digits,10,0)
and main.type = 'E'
group by type, main.digits, low
)
)
;
我希望这对某人有用!
答案 0 :(得分:1)
在大多数数据库中,您可以使用WITH子句。 HANA是否支持WITH子句/ CTE?
见下面的例子。该过程获取一次数据并根据您的喜好使用它。这将提高性能。
WITH v_criteria AS
(
SELECT type, value
FROM criteria
WHERE type IN ('I', 'E')
)
select *
from main
inner join v_criteria inc
on ColA like inc.value
and inc.type = 'I'
left outer join v_criteria exc
on ColA like exc.value
and exc.type = 'E'
where exc.value is null
;
答案 1 :(得分:1)
虽然SAP HANA确实支持公用表表达式(CTE,WITH
子句),但它对查询的性能没有帮助。
使用EXPLAIN PLAN
,您可以看到HANA对所提到的两种查询方式使用完全相同的执行计划。
OPERATOR_NAME OPERATOR_DETAILS TABLE_NAME
ROW SEARCH MAIN.COLA, INC.TYPE, INC.VALUE, INC.TYPE, INC.VALUE ?
FILTER INC.VALUE IS NULL ?
NESTED LOOP JOIN (LEFT OUTER) JOIN CONDITION: MAIN.COLA LIKE INC.VALUE ?
NESTED LOOP JOIN JOIN CONDITION: MAIN.COLA LIKE INC.VALUE ?
COLUMN SEARCH MAIN.COLA ?
COLUMN TABLE MAIN
COLUMN SEARCH INC.VALUE, INC.TYPE ?
COLUMN TABLE FILTER CONDITION: INC.TYPE = 'I' CRITERIA
COLUMN SEARCH INC.VALUE, INC.TYPE ?
COLUMN TABLE FILTER CONDITION: INC.TYPE = 'E' CRITERIA
使用此计划需要注意的是,它使用两个嵌套连接,并且两个连接都是NESTED LOOP JOINS
。
对于提供的最小数据集,这不会有什么坏处,只需将表内容扩展到100.000条记录(main
)和200,000条记录(criteria
)就会将您的数据库发送到一个冗长的CPU时间盛宴中。 / p>
有效地,系统必须对LIKE
联接中的每次迭代运行NL
比较。
根据数据,这可以将n * m个记录反馈到外部循环中,这又可以匹配m个匹配
n x m x m LIKE
比较=&gt; O(n ^ 3)
或者,您可以使用以下基于集合的查询:
/* include these */
select
main.cola
from
main
inner join criteria cr_in
on main.ColA like cr_in.value
and cr_in.type = 'I'
MINUS
/* exlude these */
select
main.cola
from
main
inner join criteria cr_in
on main.ColA like cr_in.value
and cr_in.type = 'E';
这导致以下执行计划:
OPERATOR_NAME OPERATOR_DETAILS TABLE_NAME
ROW SEARCH MAIN.COLA ?
DISTINCT GROUPING: MAIN.COLA ?
HASH JOIN (ANTI SEMI) HASH BUILD: RIGHT, JOIN CONDITION: MAIN.COLA = MAIN.COLA ?
NESTED LOOP JOIN JOIN CONDITION: MAIN.COLA LIKE CR_IN.VALUE ?
COLUMN SEARCH MAIN.COLA ?
COLUMN TABLE MAIN
COLUMN SEARCH CR_IN.VALUE ?
COLUMN TABLE FILTER CONDITION: CR_IN.TYPE = 'I' CRITERIA
NESTED LOOP JOIN JOIN CONDITION: MAIN.COLA LIKE CR_IN.VALUE ?
COLUMN SEARCH MAIN.COLA ?
COLUMN TABLE MAIN
COLUMN SEARCH CR_IN.VALUE ?
COLUMN TABLE FILTER CONDITION: CR_IN.TYPE = 'E' CRITERIA
显然,两个NESTED LOOP JOINS
仍然存在,但没有相互嵌套。合并HASH JOIN
使用两个NESTED LOOP
联接的结果集,每个联合运行一次。
这里我们最终得到了
的运行时上限NESTED LOOP JOINS
)HASH JOIN
)=&GT; O(n ^ 2)
这比以前好(并且两个NL
并行执行),但仍然不是很好。
特别是criteria
中的大型集合,您希望寻找更好的解决方案。
如果您坚持使用当前的设计方法,一种选择是在插入新条件时检查潜在的较短条件并将其保存在附加列中。
根据您希望支持的标准维护操作的类型,此任务可以变得非常复杂(例如,删除最短的条件到目前为止意味着需要找到新的最短条件并且需要更新保存的引用。
总计:在连接条件中要非常小心“动态”LIKE
运算符。