Teiid 未执行最佳连接
Teiid not performing optimal join
对于我们的 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 子句来查看下推是否发生。连接提示似乎也无关紧要。
遗憾的是,目前性能影响太大,我们无法达到我们的性能目标。
通常,exists
比 in
表现更好:
SELECT vlt.*
FROM very_large_table vlt
WHERE EXISTS (SELECT 1 FROM very_small_table vst WHERE vst.other_id = vlt.id);
但是,这可能最终会扫描大 table。
如果 id
在 vlt
中是唯一的并且在 vst
中没有重复项,那么 JOIN
可能优化得更好:
select vlt.*
from very_small_table vst join
very_large_table vlt
on vst.other_id = vlt.id;
very_small_table 和 very_large_table 有基数吗?如果不是,规划器将采用默认计划。
您还可以使用依赖连接提示:
SELECT * FROM very_large_table WHERE id IN /*+ dj */ (SELECT other_id from very_small_table)
对于我们的 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 子句来查看下推是否发生。连接提示似乎也无关紧要。
遗憾的是,目前性能影响太大,我们无法达到我们的性能目标。
通常,exists
比 in
表现更好:
SELECT vlt.*
FROM very_large_table vlt
WHERE EXISTS (SELECT 1 FROM very_small_table vst WHERE vst.other_id = vlt.id);
但是,这可能最终会扫描大 table。
如果 id
在 vlt
中是唯一的并且在 vst
中没有重复项,那么 JOIN
可能优化得更好:
select vlt.*
from very_small_table vst join
very_large_table vlt
on vst.other_id = vlt.id;
very_small_table 和 very_large_table 有基数吗?如果不是,规划器将采用默认计划。
您还可以使用依赖连接提示:
SELECT * FROM very_large_table WHERE id IN /*+ dj */ (SELECT other_id from very_small_table)