1

在 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 之间的每个数据提供了一条记录。我们已经找到了一种方法来使用返回 SQL 数组和 CROSS APPLY EXPLODE 语句的 UDF 进行爆炸。

我看到的问题是我们正在计算数百万次的日期范围,行集中的每行一次。这似乎是非常低效的,并且确实是处理时消耗时间的主要来源。

我已经创建了一种生成上面使用的日期表的方法,并且想试验性能,但是 U-SQL 连接不支持 BETWEEN 语句。

应该使用什么方法?从文档中不清楚 CROSS APPLY 是否可以处理这个问题。

如果间隔在两个日期之间,我尝试在后面的代码中使用 UDF 返回 true 或 false,但这只会导致错误 JOIN ON 子句只能在列上而不是 UDF

4

1 回答 1

3

U-SQL 在 join 的子句中不支持BETWEEN(或其他非等值连接)表达式的原因在ON这里解释:https ://msdn.microsoft.com/en-us/library/azure/mt621310.aspx 。简而言之:我们目前只想在连接语法中公开可优化的连接,并使执行成本在其他情况下更加明显。

您可以使用 a 执行连接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提出请求。

于 2016-03-23T20:04:45.343 回答