在SQL Server中,我只是一个带有BETWEEN语句的JOIN,将时间范围分解为多个间隔记录。该查询类似于
SELECT
a.UltimateID,
a.SiteID,
ProductID,
b.Date
FROM
ss_UsageTracking a
JOIN SELECTServerSchema.ss_fn_CreateDateTable(@StartDate, @EndDate, 1) b ON b.Date BETWEEN a.StartDate AND a.EndDate
这为StartDate和EndDate之间的每个数据提供了一条记录 我们已经找到了一种使用UDF进行爆炸的方法,它返回一个SQL数组和一个CROSS APPLY EXPLODE语句。
我看到的问题是我们计算的日期范围是数百万次,行集中每行一次。这似乎是非常低效的,并且确实是处理时消耗的主要来源。
我创建了一种生成上面使用的日期表的方法,并希望对性能进行试验,但是U-SQL联接不支持BETWEEN语句。
应该采用什么方法?从文档中可以看出CROSS APPLY是否可以处理这个问题。
我尝试在后面的代码中使用UDF,如果间隔在两个日期之间,则返回true或false,但是这只会导致JOIN ON子句只能出现在列而不是UDF上的错误
答案 0 :(得分:3)
此处解释了U-SQL在连接的BETWEEN
子句中不支持ON
(或其他非等值连接)表达式的原因:https://msdn.microsoft.com/en-us/library/azure/mt621310.aspx。简而言之:我们希望当前只在连接语法中公开可优化的连接,并在其他情况下使执行成本更加明显。
您可以使用CROSS JOIN
执行联接,并将BETWEEN
谓词移到WHERE
子句中。
所以而不是
@x = SELECT * FROM t JOIN s ON t.a BETWEEN s.beg AND s.end;
你写了
@x = SELECT * FROM t CROSS JOIN s WHERE t.a BETWEEN s.beg AND s.end;
或者你可以在连接之前在select子句中调用UDF,然后在equijoin中使用UDF的列。
所以而不是
@x = SELECT * FROM t JOIN s ON f(t.a) == s.b;
你会写
@t = SELECT *, f(a) AS fa FROM t;
@x = SELECT * FROM @t JOIN s ON t.fa == s.b; // note this includes fa in result
如果你觉得你更喜欢U-SQL为你做重写,代价是不太了解性能影响,请在http://aka.ms/adlfeedback提交请求。