【问题标题】:Teiid not performing optimal joinTeiid 没有执行最佳连接
【发布时间】:2020-12-03 06:02:32
【问题描述】:

对于我们的 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_table中的数据只有大约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 语句或代替 where 子句使用 join 子句来查看是否发生下推。此外,连接提示似乎并不重要。

遗憾的是,目前对性能的影响如此之大,以至于我们无法达到我们的性能目标。

【问题讨论】:

    标签: sql filter teiid


    【解决方案1】:

    very_small_table 和very_large_table 上是否有任何基数?否则,计划者将采用默认计划。

    您还可以使用依赖连接提示:

    SELECT * FROM very_large_table WHERE id IN /*+ dj */ (SELECT other_id from very_small_table)
    

    【讨论】:

    • 在较大的表上存在,但它们可能还不完全正确,因为它们假设开发数据。非常小的表是一个文本表,其中包含用户的角色。我给它的基数为 5(这是预期的最大值)。我部分解决了这个问题;它无法正常工作的原因是我在 Squirrel 中测试查询,它的行为与 DDL 不同。不知何故,依赖 IN 连接在 2500 行之后更快,但低于该值的所有内容都更快地暗示了 IN。这在很大程度上取决于场景我们需要多少行。我们可以两全其美吗?
    • 有没有办法强制执行与硬编码的 IN 子句相同的行为?因为数据量将相似,这将使其更快。有了 Prod 的成本统计信息,它现在总是忽略提示 :(.
    • 如果不了解查询计划的详细信息,就很难说两全其美。该计划还将阐明硬编码的区别是什么 - 例如,使用 dj 提示应该产生一个几乎等同于硬编码的计划,它只需要预先评估值集,我认为有一个额外的缓冲。我也不确定你忽略提示是什么意思。你得到什么计划,你期望什么计划?
    • 我们今天将进行测试,如果我们看到此设置的一些性能改进。如果这没有成功,我将在开幕帖中发布一个匿名计划。我需要改变基数来表达我的意思;但我希望性能已经可以了。
    • issues.redhat.com/browse/TEIID-6058 根据您提供的查询计划解决了您看到的主要计划问题。
    【解决方案2】:

    通常,exists 的性能优于 in

    SELECT vlt.*
    FROM very_large_table vlt
    WHERE EXISTS (SELECT 1 FROM very_small_table vst WHERE vst.other_id = vlt.id);
    

    但是,这最终可能会扫描大表。

    如果idvlt 中是唯一的并且在vst 中没有重复,那么JOIN 可能会优化得更好:

    select vlt.*
    from very_small_table vst join
         very_large_table vlt
         on vst.other_id = vlt.id;
    

    【讨论】:

    • 感谢您的回复。但是,我已经尝试存在没有太大效果。我确实得到了 5 秒,而不是 5.4 秒,但这可以忽略不计。硬编码查询的性能为 0.4 秒。联接在 6-7 秒之间的得分往往要慢一些。这只是验收数据,所以我希望生产中的数据集更大。
    猜你喜欢
    • 1970-01-01
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 2021-09-08
    • 2022-07-30
    • 1970-01-01
    相关资源
    最近更新 更多