一种基于ODPS SQL的全局字典索引分布式计算思路

简介: 本文提供一种能充分利用分布式计算资源来计算全局字典索引的方法,以解决在大数据量下使用上诉方式导致所有数据被分发到单个reducer进行单机排序带来的性能瓶颈。

在一些业务场景中,我们需要将字符串映射为一个整形数字,并确保全局唯一,比如在BitMap字典索引计算场景。常用的方法是将数据集根据需要映射的字符串做全局order by排序,将排序号作为字符串的整形映射。该方式能达到目标,但如果一次要计算的数据量太大(十亿级别或更大),会跑耗时较久甚至跑不出来。



本文提供一种能充分利用分布式计算资源来计算全局字典索引的方法,以解决在大数据量下使用上诉方式导致所有数据被分发到单个reducer进行单机排序带来的性能瓶颈。


order by方式

sort_data数据集中id已经唯一,数据量级9.3亿,直接对数据集全局开窗排序写法如下:

INSERT OVERWRITE TABLE test_data_result
SELECT  id
        ,ROW_NUMBER() OVER (ORDER BY id ASC ) AS rn
FROM    test_data
;

DAG图:

image.png

耗时30分钟,reducer只有一个,这里设置set odps.sql.reducer.instances=256是不起作用的,在这种方式下reducer只能有一个才能保证是全局唯一的。


分布式优化思路

大数据量下计算最忌讳的就是演变为单机计算,好一点的情况是跑很久,数据量再大可能直接跑不出来。如何利用计算资源水平扩展的优势来解决?思路是先做分桶进行分布式局部排序、再基于桶大小得到全局索引。类似于操作系统指令寻址的基址寻址,我们需要对每个id做绝对地址映射,利用一个基址加上相对地址得到绝对地址。

代码参考如下:


--第一步
WITH hash_bucket AS 
(
SELECT  id
            ,ROW_NUMBER() OVER (PARTITION BY bucket_no ORDER BY id ASC ) AS bucket_rel_index
            ,COUNT(1) OVER (PARTITION BY bucket_no ) AS bucket_size
            ,bucket_no
FROM    (
SELECT  id
                        ,ABS(HASH(id)) % 100000 AS bucket_no
FROM    test_data
            ) 
)
--第二步
,bucket_base AS 
(
SELECT  bucket_no
            ,SUM(bucket_size) OVER (ORDER BY bucket_no ASC ) - bucket_size AS bucket_base
FROM    (
SELECT  DISTINCT bucket_no
                        ,bucket_size
FROM    hash_bucket
            ) 
)
--第三步
INSERT OVERWRITE TABLE sort_data_result_1
SELECT  /*+ MAPJOIN(t2) */
        t1.id
        ,t2.bucket_base + bucket_rel_index AS id_index
FROM    hash_bucket t1
JOIN    bucket_base t2
ON      t1.bucket_no = t2.bucket_no
;

1.第一步先对id做hash分桶,然后计算每个桶的大小,桶数量可以根据需要计算的id数量来评估,这里分100000个桶,然后计算出每个id在桶内的相对位置bucket_rel_index,同时计算出桶大小bucket_size;


2.第二步根据桶大小计算每个桶的基址;


3.第三步将桶基址+id在桶内的相对地址得到全局唯一的绝对地址id_index;

image.png

优化后避免了单机计算,耗时2分钟。

日常优化记录,也许并非最优,如有其他方式欢迎探讨。



来源  |  阿里云开发者公众号

作者  |  云义


相关实践学习
基于MaxCompute的热门话题分析
Apsara Clouder大数据专项技能认证配套课程:基于MaxCompute的热门话题分析
相关文章
|
6月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
4月前
|
SQL 存储 分布式计算
【万字长文,建议收藏】《高性能ODPS SQL章法》——用古人智慧驾驭大数据战场
本文旨在帮助非专业数据研发但是有高频ODPS使用需求的同学们(如数分、算法、产品等)能够快速上手ODPS查询优化,实现高性能查数看数,避免日常工作中因SQL任务卡壳、失败等情况造成的工作产出delay甚至集群资源稳定性问题。
1243 36
【万字长文,建议收藏】《高性能ODPS SQL章法》——用古人智慧驾驭大数据战场
|
9月前
|
SQL 存储 关系型数据库
SQL优化策略与实践:组合索引与最左前缀原则详解
本文介绍了SQL优化的多种方式,包括优化查询语句(避免使用SELECT *、减少数据处理量)、使用索引(创建合适索引类型)、查询缓存、优化表结构、使用存储过程和触发器、批量处理以及分析和监控数据库性能。同时,文章详细讲解了组合索引的概念及其最左前缀原则,即MySQL从索引的最左列开始匹配条件,若跳过最左列,则索引失效。通过示例代码,展示了如何在实际场景中应用这些优化策略,以提高数据库查询效率和系统响应速度。
401 10
|
10月前
|
SQL 索引
【YashanDB知识库】字段加上索引后,SQL查询不到结果
【YashanDB知识库】字段加上索引后,SQL查询不到结果
|
5月前
|
SQL 分布式计算 大数据
SparkSQL 入门指南:小白也能懂的大数据 SQL 处理神器
在大数据处理的领域,SparkSQL 是一种非常强大的工具,它可以让开发人员以 SQL 的方式处理和查询大规模数据集。SparkSQL 集成了 SQL 查询引擎和 Spark 的分布式计算引擎,使得我们可以在分布式环境下执行 SQL 查询,并能利用 Spark 的强大计算能力进行数据分析。
|
7月前
|
SQL 人工智能 分布式计算
别再只会写SQL了!这五个大数据趋势正在悄悄改变行业格局
别再只会写SQL了!这五个大数据趋势正在悄悄改变行业格局
156 0
|
9月前
|
SQL 关系型数据库 MySQL
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL 数据库 SQL 语句调优方法详解(2-1)
本文深入介绍 MySQL 数据库 SQL 语句调优方法。涵盖分析查询执行计划,如使用 EXPLAIN 命令及理解关键指标;优化查询语句结构,包括避免子查询、减少函数使用、合理用索引列及避免 “OR”。还介绍了索引类型知识,如 B 树索引、哈希索引等。结合与 MySQL 数据库课程设计相关文章,强调 SQL 语句调优重要性。为提升数据库性能提供实用方法,适合数据库管理员和开发人员。
|
10月前
|
SQL 大数据 数据挖掘
玩转大数据:从零开始掌握SQL查询基础
玩转大数据:从零开始掌握SQL查询基础
386 35