【问题标题】:U-sql Inner JOIN taking too longU-sql Inner JOIN 耗时太长
【发布时间】:2023-03-27 02:34:01
【问题描述】:

下面是我做的一个JOIN。我相信它没有效率。我的 u-sql 工作需要很长时间,已经六个多小时了。我也有很多数据。在下面的示例中,我的输入是 2 GB(数百万个文件夹)LHS 和 RHS。

我需要在深度方面找到子目录计数,在我的示例中,根目录是 adl://x.azuredatalakestore.net/

预期的最终结果如下,目录中的每个级别都有所有子目录的总和。

| WorkDir| Depth  | Dir                                                  | NumberOfSubDirectories | IsDirectory|
|       -----------------------------------------------------------------------------------------|
| /      | 0      |adl://x.azuredatalakestore.net/                       | 5                      |  True      |
| /      | 1      |adl://x.azuredatalakestore.net/backup/                | 4                      |  True      |
| /      | 2      |adl://x.azuredatalakestore.net/backup/jenkins/        | 0                      |  True      |
| /      | 2      |adl://x.azuredatalakestore.net/backup/viewer/         | 2                      |  True      |
| /      | 3      |adl://x.azuredatalakestore.net/backup/viewer/2018/    | 1                      |  True      |
| /      | 4      |adl://x.azuredatalakestore.net/backup/viewer/2018/07/ | 0                      |  True      |

加入的输入。左侧(LHS)和右侧(RHS)是同一张表

WorkDir Depth Dir IsDirectory
/ 0 adl://x.azuredatalakestore.net/ TRUE
/ 1 adl://x.azuredatalakestore.net/backup/ TRUE
/ 2 adl://x.azuredatalakestore.net/backup/jenkins/ TRUE
/ 2 adl://x.azuredatalakestore.net/backup/viewer/ TRUE
/ 3 adl://x.azuredatalakestore.net/backup/viewer/2018/ TRUE
/ 4 adl://x.azuredatalakestore.net/backup/viewer/2018/07/ TRUE

我的加入声明

          // Get Sub Directory from Directory list  
@DirWithSubDir =
    SELECT 
           b.WorkDir AS WorkDirD,
           b.Depth AS DepthD,
           b.Dir AS DirD,
           b.IsDirectory AS IsDirectoryD,
           COUNT(b.Dir)-1 AS NumberOfSubDirectoriesD 
    FROM @stream_information AS a
         JOIN
             @stream_information AS b
         ON a.IsDirectory == b.IsDirectory
    WHERE a.Dir.Contains(b.Dir)
    GROUP BY b.WorkDir,
           b.Depth,
           b.Dir,
           b.IsDirectory
     ;

我有另一个连接语句,我以文件夹的字节为单位获取数据,它与此类似,也很慢。

【问题讨论】:

  • ADLS Gen 1 将于 2024 年 2 月退役。虽然这可能看起来还很遥远,但我们已经快到 2022 年了,所以如果您有机会改变路线,例如在 Databricks、Azure Synapse Analytics 中重构或其他引擎,你应该接受它。有关详细信息,请参阅this post。 U-SQL 没有那么多用于调优的统包设置(尽管您可以应用一些提示),我认为您的基本问题是拥有如此多的文件(数百万)。考虑使用另一种技术和/或将您的文件合并到更大的文件中。
  • 谢谢@wBob。您最好尽快从 ADLS gen1 迁移到 ADLS Gen2。微软有一个很好的解决方案来迁移到 ADLS Gen2 docs.microsoft.com/en-us/azure/storage/blobs/…

标签: join azure-data-lake u-sql


【解决方案1】:

我们可以组合每一行的所有目录,然后在同一个记录集上进行内部连接。 “Dir.Contains(b.Dir)”连接是交叉连接,因此非常昂贵。

// make Dir Array 
SELECT  
        *,
        SqlArray.Create(Dir.Split('/')) AS DirArray
FROM @rowset
;


//
//  for each stream "adl://x.azuredatalakestore.net/a/b/" we explode this to :-
//  { "adl://x.azuredatalakestore.net/" , "adl://x.azuredatalakestore.net/a/","adl://x.azuredatalakestore.net/a/b/" }

@subDirExplode =
SELECT SubPath,StreamName
FROM @stream_information_Dir
    CROSS APPLY   
          EXPLODE( Enumerable.Range(3, DirArray.Count() - 3).// for each in array where each dir combination exists
                                                            Select(n=> string.Join("/", DirArray.Take(n)) + "/")) AS r(SubPath) // get all elements 3 to count and make cobinations  
   ;

// count all combination as the number of sub directories 
@dir_with_count =
SELECT 
        l.StreamName AS StreamName,
        COUNT(r.SubPath) -1  AS NumberOfSubDirectories
FROM @stream_information_Dir AS l
     LEFT OUTER JOIN
         @subDirExplode AS r
     ON l.StreamName == r.SubPath
GROUP BY 
         l.StreamName
   ;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    相关资源
    最近更新 更多