正如this answer所述,无法优化JOIN ON
与OR
相结合。我确实注意到我正在尝试编写的查询中的可怕性能。
要描述我的场景,应返回标题记录以及来自所有相关项目记录的数据。项目可以基于三个字段之一与标题记录相关。以下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方法。这不仅仅是因为我想避免这种重复级别,而且查询的其余部分虽然经过优化,但本身却非常昂贵。有没有我没见过的替代方案?
答案 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} 不可归。