我们正在尝试在 Snowflake 中实现间隔值的添加。由于 Snowflake 中不支持间隔数据类型,我们正在尝试使用 UDF 来实现相同的功能。我们将间隔转换为秒,在获得总秒数后,我们将总秒转换为所需的目标间隔类型。
我们使用 SQL UDF 和 Javascript UDF 实现了相同的逻辑。
Javascript UDF
create or replace function js_interval(interval_1 string, interval_sign_1 double, interval_2 string, interval_sign_2 double)
returns string
language javascript
strict
as '
if ((INTERVAL_1.substring(0,1)=="-"))
{
var res = INTERVAL_1.split(":");
var res2=(res[1]*-60+res[0]*3600);
var res3= -1*res[2];
}
else
{
var res = INTERVAL_1.split(":");
var res2=(res[1]*60+res[0]*3600);
var res3= res[2];
}
if ((INTERVAL_2.substring(0,1)=="-"))
{
var res11 = INTERVAL_2.split(":");
var res22=(res11[1]*-60+res11[0]*3600);
var res33= -1*res11[2];
}
else
{
var res11 = INTERVAL_2.split(":");
var res22=(res11[1]*60+res11[0]*3600);
var res33= res11[2];
}
if(INTERVAL_SIGN_1 > 0)
{
var result1= res2*1+res3*1;
}
else
{
var result1=(res2*1+res3*1)*-1;
}
if(INTERVAL_SIGN_2 > 0)
{
var result2= res22*1+res33*1;
}
else
{
var result2=(res22*1+res33*1)*-1;
}
var final_sec= result1+result2;
if (final_sec < 0 )
{
return "-"+String(Math.trunc(Math.abs(final_sec)/3600))+":"+String(Math.trunc(Math.abs(final_sec)/60)%60)+":"+String(Math.abs(final_sec)%60);
}
else
{
return String(Math.trunc(Math.abs(final_sec)/3600))+":"+String(Math.trunc(Math.abs(final_sec)/60)%60)+":"+String(Math.abs(final_sec)%60);
}
';
SQL UDF
create or replace function addIntervalsH2S ( interval_1 varchar, interval_type_1 varchar , interval_sign_1 int, interval_2 varchar, interval_type_2 varchar, interval_sign_2 int )
returns varchar
as
'select trunc((((split_part(interval_1,\':\',1)*3600+split_part(interval_1,\':\',2)*60+split_part(interval_1,\':\',3))*interval_sign_1)+((split_part(interval_2,\':\',1)*3600+split_part(interval_2,\':\',2)*60+split_part(interval_2,\':\',3))*interval_sign_2))/3600)||\':\'||mod(trunc((((split_part(interval_1,\':\',1)*3600+split_part(interval_1,\':\',2)*60+split_part(interval_1,\':\',3))*interval_sign_1)+((split_part(interval_2,\':\',1)*3600+split_part(interval_2,\':\',2)*60+split_part(interval_2,\':\',3))*interval_sign_2))/60),60)||\':\'||mod((((split_part(interval_1,\':\',1)*3600+split_part(interval_1,\':\',2)*60+split_part(interval_1,\':\',3))*interval_sign_1)+((split_part(interval_2,\':\',1)*3600+split_part(interval_2,\':\',2)*60+split_part(interval_2,\':\',3))*interval_sign_2)),60)
end';
对于嵌套级别间隔添加查询,基于 Javascript 的 UDF 的性能要好于基于 SQL 的 UDF。
造成巨大性能差异的原因可能是什么?