Sql m必须对NL联接中的每个迭代运行类似的比较。 根据数据的不同,这可以将n*m条记录反馈回外部循环,而外部循环也可以命中m条匹配
nxmxmSql m必须对NL联接中的每个迭代运行类似的比较。 根据数据的不同,这可以将n*m条记录反馈回外部循环,而外部循环也可以命中m条匹配,sql,hana,Sql,Hana,nxmxmLIKE比较=>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 */ se
LIKE
比较=>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
显然,这两个嵌套循环联接仍然存在,但没有嵌套到彼此中。组合散列联接
将两个嵌套循环
联接的结果集合并为一个,每个结果集只运行一次
在这里,我们的运行时上限为
- 2 x(n x m)(用于两个
嵌套循环联接
)
- 2*m(用于
散列联接
)
=>O(n^2)
这比以前好(两个NL
s也并行执行),但仍然不是很好。
尤其是对于标准中的大型集合
,您需要寻找更好的解决方案
如果使用当前的设计方法,一个选项是在插入新条件时检查可能较短的条件,并将其保存在其他列中
根据您希望支持的标准维护操作的类型,此任务可能会变得非常复杂(例如,删除到目前为止的最短条件意味着需要找到新的最短条件,并且需要更新保存的引用)
总之:对“动态”要相当小心像联接条件中的
运算符。不知道WITH子句。是的,它提高了性能,谢谢。不知道WITH子句。是的,它提高了性能,谢谢。谢谢@Lars。所以性能的提高纯粹是运气好吗?我曾想过使用减号
运算符的解决方案,但p问题是,我所展示的main
table实际上是一组查询,而不是一个表。采用这种方法会更好吗?还是应该尝试一个表函数或一个计算视图?当视图定义未知时,无法对视图上的执行计划进行假设;必须检查fin使用EXPLAIN PLAN
进行查询。如上所述,只要有更多数据,尤其是标准端的数据更多,整个设计就不允许有良好的性能。如果您以某种方式确保只有一小部分条件,您可能可以使用这两种方法。我的主要问题是,标准表是ilt来自作为输入参数的字符串。我现在将其转换为范围表。当我将它们连接在一起时,我将其转换为单个嵌套循环连接
,因为我现在只在我需要的范围上使用介于
之间。不过,还有更好的方法吗?谢谢@Lars。所以性能改进纯粹是运气好吗?我我曾想过使用减号
运算符的解决方案,但问题是,我显示为主
表的实际上是一组查询,而不是一个表。使用这种方法是否更好?还是应该尝试表函数或计算视图?无法对执行pl进行假设当视图定义未知时,视图将被覆盖;为此,必须使用EXPLAIN PLAN
检查最终查询。如上所述,只要有更多的数据,尤其是条件端的数据,整个设计就不允许有良好的性能。如果您以某种方式确保只有一小部分条件,您可能会这两种方法都可以。我的主要问题是,criteria表是从作为输入参数的字符串构建的。我现在正在将其转换为范围表。当我将它们连接在一起时,我将其转换为单个嵌套循环连接,因为我现在只在需要的范围上使用介于之间。但是,是否会有更好的方式?
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
;
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
)
)
;
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
;
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
/* 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