join - 左连接的 Hive 倾斜缓解
问题描述
我有一个影响左外连接性能的经典倾斜问题(左表是“大”,右表是“小”)。倾斜的键主要是 NULL(很长的路要走),其次是“keyX”。
我尝试了一些不同的东西:
- 在倾斜的键上添加连接谓词“IS NOT NULL”似乎没有任何明显的影响。而且我还有“keyX”要处理
- 我使用 hive.optimize.skewjoin 的结果好坏参半
- 我发现几篇文章中提到的“关键盐渍”技术效果很好(快 3 倍 - 4 倍)!但我注意增加查询的复杂性,它确实需要修改每个问题查询,教育各种其他工程师等
- 我刚刚注意到一个非常有前途的功能,您可以在元存储中指定倾斜并让 hive 使用它来生成倾斜优化的执行计划。在我回到选项 3 之前,我很想对此进行测试,但我似乎无法将 NULL 放入倾斜值列表中。它会接受这个:
alter table T skewed by (skewed_key) on ('keyX');
但不是这个:
alter table T skewed by (skewed_key) on ('keyX',NULL);
任何想法这种语法有什么问题?还是此功能不接受 NULL Skew Values?
我一般也对偏斜问题的其他解决方案持开放态度:)
解决方案
我的 5 美分:我不打算完全解决这篇文章中的歪斜问题。只是提供一些关于倾斜的 NULL 连接键以及我如何解决它的信息,希望它会有用
是的,“key salting”有效,其他一切似乎都不稳定或根本不起作用。
如果倾斜键为 NULL 并且所有 NULL 记录都被分配到同一个 reducer,您可以通过将 NULL 键转换为不在允许范围内的随机键值来解决它,这样它们就不会被连接而是均匀分布到许多减速机。
像这样的东西:
LEFT JOIN asset_dim p ON NVL(f.asset_id, -9999999+RAND()*1000.0)%1000) = p.asset_id
这种方法依赖于这样一个事实,即您在范围内永远不会有否定键 - 9999999 ... - 9998000
对于非 NULL 倾斜键,这种方法很危险,尤其是当您在带有点节点的 EMR 上运行时,这可能会在运行时丢失。重新运行容器将产生不同的 RAND,并且相同的记录将被传递给不同的 reducer,这将导致部分数据重复或丢失,但对于未加入 NULL 的这种特殊情况,它可以正常工作。
同样对于“KeyX”显式拆分连接 + UNION ALL 工作正常,但解决方案有点麻烦:
(select * from t1 where key!='KeyX') left join t2 on t1.key=t2.key --everything else
UNION ALL
(select * from t1 where key=='KeyX') left join t2 on t1.key=t2.key --skewed
推荐阅读
- flutter - 我可以在颤动中播放来自 base64 字符串的视频吗?
- symfony - 更新 Composer 时遇到问题
- sqlite - 如果最后一个值等于,SQLite3 表约束不插入数据
- godot - tile_get_texture() 返回整个图块集
- .net - 运行 ASP.NET 应用程序显示错误 500,但 .NET CORE 运行良好
- powerbi - DAX 如何从月份计算过去 4 个月是月份切片器的选择?
- list - Kotlin 在 mutableList 中查找重复项
- php - 使用带有 Nova 按钮的 Laravel 事件/监听器
- sql - 带逗号的 Zabbix 键
- oracle - :new 和 :old 值在 oracle 触发器中动态变化