优化JOIN ON或不重复查询每个OR

时间:2015-08-18 10:01:19

标签: sql join optimization hana

正如this answer所述,无法优化JOIN ONOR相结合。我确实注意到我正在尝试编写的查询中的可怕性能。

要描述我的场景,应返回标题记录以及来自所有相关项目记录的数据。项目可以基于三个字段之一与标题记录相关。以下SQL看起来语法合理,但由于无法优化JOIN ON OR:

,因此非常昂贵
SELECT
    header.a,
    header.b,
    item.x,
    item.y,
    item.z
    FROM header
    LEFT OUTER JOIN item    ON item.x   = header.a
                            OR item.y   = header.a
                            OR item.z   = header.b;

请注意,这是从一个非常复杂的查询推广出来的(还有另外6个连接和各种过滤器)。我希望JOIN ON OR实现可行,但我无法确认,因为OR产生的全表扫描可能需要几个小时才能完成。 (额外问题:三重条件会导致单个顺序FTS还是三个连续FTS?)

由于周围查询的复杂性,我想避免链接答案中建议的UNION ALL方法。这不仅仅是因为我想避免这种重复级别,而且查询的其余部分虽然经过优化,但本身却非常昂贵。有没有我没见过的替代方案?

2 个答案:

答案 0 :(得分:1)

虽然我认为你的整体查询中存在很多复杂性,但我建议在这种情况下拆分执行并实际使用SQLScript。

由于您有三种不同的方式来处理相关的标题和项目,因此会产生三个查询。 使用SQLScript,可以将这三个简单的连接查询分配给三个单独的表变量。

然后可以非常有效地处理这些连接中的每一个,并且还可以一次执行所有这三个连接。这不会减少整体工作,但会缩短总执行时间。

此外,根据查询的性质,您可以将三个表变量合并,并将它们用作复杂剩余计算的输入。

在任何情况下:这些是你的表之间的三个独立的联系,并且似乎是最优雅和有效的,不试图将它们塞进一个所有SQL的母亲和#34;陈述: - )

答案 1 :(得分:1)

这可能看起来很难看,但它避免了OR,并且有可能使用索引(如果存在):

SELECT
    header.a
    , header.b
    , COALESCE(i1.x, i2.x, i3.x) AS itemx
    , COALESCE(i1.y, i2.y, i3.y) AS itemy
    , COALESCE(i1.z, i2.z, i3.z) AS itemz
    FROM header h0
    LEFT OUTER JOIN item i1 ON i1.x = h0.a
    LEFT OUTER JOIN item i2 ON i2.y = h0.a
    LEFT OUTER JOIN item i3 ON i3.z = h0.b
        ;

注意:确实假设该项。{x.y,z} 不可归