sql—有效地连接两个具有多个位置的表

bvjxkvbb  于 2021-08-13  发布在  Java
关注(0)|答案(3)|浏览(353)

当我尝试连接两个大表并使用 WHERE...OR 条款:

SELECT A.a, B.b 
FROM A JOIN B 
ON A.equal = B.equal 
WHERE A.condition1 > 100 OR B.condition2 > 200

这里a和b是非常大的表,条目需要与 WHERE...OR 不同表中的条件。请问有什么方法可以优化这个条款吗?
提前打电话。

qlckcl4x

qlckcl4x1#

OR 条件通常是性能杀手。
如果您的查询运行缓慢,您可以尝试的另一种方法是 union 两个子查询,如:

SELECT A.a, B.b 
FROM A JOIN B ON A.equal = B.equal 
WHERE A.condition1 > 100
UNION
SELECT A.a, B.b 
FROM A JOIN B ON A.equal = B.equal 
WHERE B.condition2 > 100

你想要索引吗 A(condition1, equal) 以及 B(condition2, equal) 为了表现。
如果可以保证子查询的结果集之间没有重叠(即没有同时满足这两个条件的行),那么可以更改 UNIONUNIN ALL :由于数据库不需要跨结果集查找重复项,因此效率要高得多。

pbwdgjma

pbwdgjma2#

这是gmb答案的一个变体。但因为你关心性能,所以值得强调。你想用 UNION ALL 具有适当的索引:

SELECT A.a, B.b 
FROM A JOIN B ON A.equal = B.equal 
WHERE A.condition1 > 100
UNION ALL
SELECT A.a, B.b 
FROM A JOIN B ON A.equal = B.equal 
WHERE B.condition2 > 100 AND A.condition1 <= 100;

使用 UNION ALL 删除删除重复项的步骤。
以上假设 A.condition1 永远不会 NULL . 这很容易处理,但只是使查询复杂了一点。
在hive中,只有当其中一个或两个条件都具有相当的选择性时,这才能真正提高性能——通过减少在hive中匹配的行数 JOIN . 如果每一个都选择,比如说,90%的行,那么您的版本可能非常相似。
如果数据库可以使用索引,则需要:
A(condition1, equal, a) B(equal, b) B(condition2, equal, b) A(equal, a, condition1)

8fq7wneg

8fq7wneg3#

研究执行日志。如果是倾斜(单个减速器运行缓慢),请参阅此答案。如果没有歪斜,那么
尝试增加平行度:
tez上Map器的示例设置:

set hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
set tez.grouping.max-size=32000000;
set tez.grouping.min-size=32000;

如果决定在mr而不是tez上运行,则Map器的示例设置:

set mapreduce.input.fileinputformat.split.minsize=32000; 
set mapreduce.input.fileinputformat.split.maxsize=32000000;

--减速器设置示例:

set hive.exec.reducers.bytes.per.reducer=32000000; --decrease this to increase the number of reducers, increase to reduce parallelism

播放这些设置。成功的标准是更多的Map器/还原器,你的Map和还原阶段运行得更快。
另请参见:https://stackoverflow.com/a/48487306/2700344
@如果条件是选择性的,并且较小的过滤数据集适合内存(在联接之前),并且启用了Map联接,则gordonlinoff配方可以正常工作: set hive.auto.convert.join=true;

相关问题