Azure 数据仓库生成串行更快的查询

Azure Data Warehouse Generate serial faster query

环境是 Azure DW 我有一个像下面这样的原始 table;

ID   Start   End   Action        date
1     10     15    Processed     25-10-2019
2     55     105   In-Progress   21-10-2019
.....

我需要 expand/transform 开始和结束列,以便它们成为序列号;

SN      Action        date
10      Processed     25-10-2019
11      Processed     25-10-2019
12      Processed     25-10-2019
13      Processed     25-10-2019
14      Processed     25-10-2019
.....

Azure 数据仓库不支持递归 CTE 或游标。所以,尝试了一个 while 循环,



create table #temp_output (SerialNumber int not null, startSerialNumber int not null, endSerialNumber int not null);
insert into #temp_output select startSerialNumber, startSerialNumber, endSerialNumber from  dbo.raw
declare @rowcount int, @cnt int, @start int, @end int
set @cnt = 1
set @rowcount = (select count(*) from dbo.raw)
while @cnt <= @rowcount
begin
select top (@cnt) @start = startSerialNumber from dbo.raw
select top (@cnt) @end = endSerialNumber from dbo.raw
while @start <= @end
begin
       insert #temp_output
       select max(SerialNumber) + 1,
       startSerialNumber,
       endSerialNumber
       from #temp_output group by startSerialNumber, endSerialNumber having max(SerialNumber) < endSerialNumber
       set @start = @start + 1
       end
       set @cnt = @cnt + 1
       end
       select SerialNumber, startSerialNumber, endSerialNumber from #temp_output_delta order by SerialNumber

然而,这需要很长时间(6 小时,当我取消查询时),因为原始 table 有 5000 万行。

需要更好的方法。

更新信息 2019 年 10 月 31 日

源 table 的分布是散列。 500 元。 源代码中有 6000 万行 table。 开始和结束之间的平均差异 3000。 起步也可以是200万。 main table 上没有索引。 列数 15 原始 table.

上的聚集列存储索引

您的样本不完整,但您不需要循环。您可以使用 BETWEEN

将其加入计数 table

如果你有一个计数 table(这是一个 table,里面只有从 1 到... 100 万的数字)

 SELECT T.TallyNumber As SN, E.Action, E.Date
 FROM YourTable E
 INNER JOIN TallyTable As T
 ON T.TallyNumber BETWEEN E.Start AND E.End

由于您要将其加载到新的 table,因此您应该使用 CTAS

CREATE TABLE [dbo].[NewTable]
WITH
(
 DISTRIBUTION = HASH([Start])
 ,CLUSTERED COLUMNSTORE INDEX
)
AS
 SELECT T.TallyNumber As SN, E.Action, E.Date
 FROM YourTable E
 INNER JOIN TallyTable As T
 ON T.TallyNumber BETWEEN E.[Start] AND E.[End];

注意 DISTRIBUTION 周围有很多设计。您需要正确执行此操作以提高性能。上面的语句只是一个例子。您可能应该使用不同的散列。

您需要获得两个源 table 的分布以及目标 table 的分布才能获得良好的性能。