所以我目前有一个非常大的表,我需要经常查询。这个表有很多列和行,我需要根据放在2个虚拟表中的2个列表来过滤行,我希望结果与其中任何一个匹配
我正在执行一个获取结果的过程,但是我们的开发环境没有足够的样本大小来测试过程性能。所以现在我有两个选择。
使用LEFT JOINS
执行此类操作
SELECT GT.* FROM GiantTable GT
LEFT JOIN List1 L1 ON GT.X = L1.X
LEFT JOIN List2 L2 ON GT.Y = L2.Y
WHERE L1.X IS NOT NULL OR L2.Y IS NOT NULL
使用2个JOIN
个查询和UNION
结果
SELECT GT.* FROM GiantTable GT JOIN List1 L1 ON GT.X = L1.X
UNION
SELECT GT.* FROM GiantTable GT JOIN List2 L2 ON GT.Y = L1.Y
我很确定第二名应该表现得更好但我想知道我是不是错了
答案 0 :(得分:1)
UNION
是有问题的,因为它需要从两个子查询的结果中过滤掉重复项。您应该能够使用EXISTS
运算符和一对相关子查询获得不错的性能:
SELECT *
FROM GiantTable GT
WHERE (EXISTS (SELECT * FROM List1 L1 WHERE L1.X = GT.X))
OR (EXISTS (SELECT * FROM List2 L2 WHERE L2.Y = GT.Y))
答案 1 :(得分:1)
你可以用
做得更好select *
from gianttable
where x in (select x from L1) or y in (select y from L2)
修改强>:
OP报告此版本比原始版本慢。这可能是真的,特别是如果x
和y
在gianttable
中编入索引(它们是各自列表中的主键,因此 在较小的列表中编入索引表)。阻碍OR
条件中where
运算符的因素 - 这意味着这两个条件都不能用作访问谓词。
还有一件事要尝试......索引应该真正有用。下面的查询等同于OP的首次尝试,也是我的第一次尝试(上图)和dasblinkenlight的解决方案。 (这是因为x
和y
在各自的列表中都是PK,所以我们不需要在那里处理null
。)
select * from gianttable where x in (select x from L1)
union all
select * from gianttable where y in (select y from L2) and x not in (select x from L1)