暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

OceanBase数据库get_hash_value函数改造&性能优化方案

IT那活儿 2025-02-06
297
点击上方“IT那活儿”公众号--专注于企业全栈运维技术分享,不管IT什么活儿,干就完了!!!  

  
Oracle数据库中出现dbms_utility.get_hash_value函数生产调用,但此函在OB侧调用会消耗高cpu。dbms_utility.get_hash_value替换为ora_hash会避免OB侧cpu高消耗情况,但ora_hash的使用方式与dbms_utility.get_hash_value不同,需要进行相应的sql改造。



函数介绍

DBMS_UTILITY.GET_HASH_VALUE (

    name        VARCHAR2, 

    base          NUMBER, 

    hash_size   NUMBER)

RETURN NUMBER;

参数说明:

name

要进行哈希计算的字符串。

base

开始返回的哈希值的基值

hash_size

所需的哈希表大小。

回值:基于输入字符串的哈希值。

ORA_HASH(expr [, max_bucket [, seed_value ]])

参数说明:

expr

通常为数据库表的列名,数据类型可以是数值类型、字符类型、日期时间类型或 RAW 类型。

max_bucket

确定哈希函数返回的最大桶值,为可选项。取值范围为 [0, 4294967295],默认值是 4294967295。

seed_value

使数据库能够为同一组数据生成不同的结果,为可选项。取值范围为 [0, 4294967295],默认值为 0。

返回值:返回一个带随机数的hash值。


改造方案

2.1 方案

dbms_utility.get_hash_value(?,?,?) 

改造为  

ora_hash(?,?,?)

2.2 样例
select ROWID, t.*
  from (select a.*
          from T_XX_XXX_XXXX_01 a
         where a.state = 0
         order by a.create_date) t
 where mod(dbms_utility.get_hash_value(rowid110000), 5) = 4
   and rownum <= 1000

改造为:

select ROWID, t.*
  from (select a.*
          from T_XX_XXX_XXXX_01 a
         where a.state = 0
         order by a.create_date) t
 where mod(ora_hash(rowid99999999) + 15) = 4
   and rownum <= 1000


改造验证

3.1 原始验证
select mod(dbms_utility.get_hash_value(rowid120), 5), count(1)
  from T_XX_XXX_XXXX_01 t
 group by mod(dbms_utility.get_hash_value(rowid120), 5)
 order by 1;

3.2 改造后验证
select mod(ora_hash(rowid1919) + 15), count(1)
  from T_XX_XXX_XXXX_01 t
 group by mod(ora_hash(rowid1919) + 15)
 order by 1;

总 结:

改造为ora_hash函数后,效率相对较高,而且数据分布均匀,每个hash桶中数据条数相差不大,与dbms_utility.get_hash_value函数结果相对一致。


END


本文作者:王亚奇(上海新炬中北团队)

本文来源:“IT那活儿”公众号

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论