对于我们的Teiid Springboot项目,我们在where子句中使用行过滤器来确定用户获得的结果。示例:
SELECT * FROM very_large_table WHERE id IN ('01', '03')
我们希望in子句中的上下文是动态的,如下所示:
SELECT * FROM very_large_table WHERE id IN (SELECT other_id from very_small_table)
现在的问题是,Teiid从very_large_table获取所有数据,然后才尝试使用where子句进行过滤,这会使查询速度减慢10-20倍。这个very_small_tableis中的数据大约只有1-10条记录,而且它是基于我们从Java获得的用户上下文。
very_large_table位于Oracle数据库上,very_small_table位于Teiid Pod/Container上。不知何故,我不能强制Teiid将数据发送到Oracle并在那里执行过滤。
我尝试过的东西:我已经指定了外部数据包装器,如下所示
CREATE FOREING DATA WRAPPER "oracle_override" TYPE "oracle" OPTIONS (EnableDependentsJoins 'true');
CREATE SERVER server_name FOREIGN DATA WRAPPER "oracle_override";
我也尝试过,使用exists语句,或者使用join子句代替where子句来查看是否发生了下推。此外,连接的提示似乎无关紧要。
遗憾的是,目前的性能影响是如此之高,以至于我们无法达到我们的性能目标。
发布于 2020-12-02 22:02:33
very_small_table和very_large_table上有没有基数?如果不是,计划器将采用默认计划。
您还可以使用从属联接提示:
SELECT * FROM very_large_table WHERE id IN /*+ dj */ (SELECT other_id from very_small_table)
发布于 2020-11-27 14:33:19
通常,exists
比in
的性能更好
SELECT vlt.*
FROM very_large_table vlt
WHERE EXISTS (SELECT 1 FROM very_small_table vst WHERE vst.other_id = vlt.id);
但是,这最终可能会扫描大表。
如果id
在vlt
中是唯一的,并且vst
中没有重复项,那么JOIN
可能会优化得更好:
select vlt.*
from very_small_table vst join
very_large_table vlt
on vst.other_id = vlt.id;
https://stackoverflow.com/questions/65039062
复制相似问题