多个列上的连接是否存储笛卡尔积?

时间:2018-05-22 22:03:27

标签: azure-data-lake u-sql

我将一个脚本从T-SQL音译到U-SQL,并遇到了一个运行该作业的问题,即它似乎被卡住了#34;在其中一个阶段 - 在2.5小时之后,工作图表显示它已经读取了200MB并且写了超过3TB但是没有接近完成。 (没有截屏,对不起。)

我将其跟踪到其中一个查询加入一个包含3400万行的表两次到1600行的表中:

@ProblemQuery = 
  SELECT
    gp.[Group],      // 16 groups
    gp.[Percentile], // 1-100
    my_fn(lt1.[Value], lt2.[Value], gp.[Value]) AS CalculatedNumber
  FROM
    @LargeTable AS lt1
    INNER JOIN @GroupPercent AS gp
      ON lt1.[Group] == gp.[Group]
      AND lt1.[Row ID] == gp.[Row ID 1]
    INNER JOIN @Large Table AS lt2
      ON gp.[Group] == lt2.[Group]
      AND gp.[Row ID 2] == lt2.[Row ID]
;

似乎在处理期间存储了完整的笛卡尔积(~2e18行),而不仅仅是过滤的1600行。我的第一个想法是,可能是使用AND而不是&&,但改变这一点没有任何区别。

我设法解决了这个问题,将一个查询与两个连接分成两个查询,每个查询一个连接,整个工作在15分钟内完成,没有存储井喷。

但是我不清楚当在连接中使用多个列或错误时这是完全预期的行为,以及是否有更好的方法来处理这类事情。我有另一个类似的查询要拆分(连接条件更多,连接条件中有更多列)我无法帮助,但我觉得这样做的方法不那么混乱

1 个答案:

答案 0 :(得分:1)

U-SQL应用了一些连接重新排序启发式(虽然我不知道它如何处理明显的自连接)。我怀疑它与您在连接谓词中使用多个列有关。我假设我们的启发式可能已关闭。你可以请求提交事件或将工作链接发送到microsoft dot com的[usql]吗?这样我们就可以调查导致优化器选择更糟糕计划的原因。

在此之前,将连接拆分为两个语句,从而强制更好的连接顺序是最好的解决方法。