我正在尝试加速这个递归的UNION ALL,如下所示,但我想不出怎么做。也许是一段时间循环,但我不确定。移动数据存储为一长串编码的移动数据,并且脚本递归地调用select语句来解析/提取该数据,然后将其全部转换。
我真的想更多地了解加快所有递归联合或寻找其他方法。我不相信索引是一个问题所以这不是一个可能的解决方案。
"的RouteData"是由固定长度间隔解析的长字符串。
以下是编码数据的示例:
ScenarioPID : 3
LegID :1
RoutePart : 0x0000000000000000000100000000000000000000000000
RouteData : 0x40323AAAAAAAAAAB00013FA6FFD663CCA3310000001F00403 ... (goes on)
cnt : 37
sequence : 1
StartTime : 8828
对于一个曲目,最终输出数据如下所示。
ScenarioPID LegID sequence TrackID Offset TimeOffset Length StartTime
3 1 1 1 0 0 6300 8828
3 1 2 1 0.0449 31 6300 8828
3 1 3 1 0.8942 325 6300 8828
3 1 4 1 0.9736 356 6300 8828
3 1 5 1 1 369 6300 8828
USE nss_demo;
DECLARE @scenario1 INT;
DECLARE @DAY_START INT;
DECLARE @DAY_END INT;
DECLARE @TRAIN_TYPE VARCHAR(50);
DECLARE @TRACK_TYPE VARCHAR(50);
SET @scenario1 = 3;
SET @DAY_START = 0;
SET @DAY_END = 7;
SET @TRAIN_TYPE = 'Empty Train';
SET @TRACK_TYPE = 'East Track';
DECLARE @KM_START INT;
DECLARE @KM_END INT;
SET @KM_START = 0;
SET @KM_END = 200;
WITH movement
AS (SELECT m.scenariopid,
m.legid,
Substring(routedata, 1, 23) AS RoutePart,
Substring(routedata, 24, Len(routedata) - 23) AS RouteData,
Len(routedata) / 23 - 1 AS cnt,
1 AS sequence,
m.starttime
FROM output.movement m
WHERE scenariopid = @scenario1
AND m.starttime BETWEEN ( @DAY_START * 86400 ) AND
( @DAY_END * 86400 )
UNION ALL
SELECT scenariopid,
legid,
Substring(m1.routedata, 1, 23) AS RoutePart
,
Substring(m1.routedata, 24,
Len(m1.routedata) - 23) AS RouteData,
Len(m1.routedata) / 23 - 1 AS cnt,
sequence + 1 AS sequence,
m1.starttime
FROM movement m1
WHERE m1.cnt > 0),
casttable
AS (SELECT tt.scenariopid,
tt.legid,
tt.sequence,
tt.trackid,
tt.offset,
tt.timeoffset,
tr.[length],
tt.starttime
FROM (SELECT scenariopid,
legid,
sequence,
Cast(trackidbin AS SMALLINT) AS TrackID,
Sign(Cast(offsetbin AS BIGINT)) *
( 1.0 +
( Cast(offsetbin AS BIGINT) & 0x000FFFFFFFFFFFFF ) *
Power(Cast(2 AS FLOAT), -52) )
*
Power(Cast(2 AS FLOAT), ( Cast(offsetbin AS BIGINT) &
0x7ff0000000000000
) /
0x0010000000000000
- 1023) AS Offset,
Cast(timebin AS INT) AS TimeOffset,
starttime AS StartTime
FROM (SELECT legid,
scenariopid,
sequence,
Substring(routepart, 9, 2) AS TrackIDBin,
Substring(routepart, 11, 8) AS OffsetBin,
Substring(routepart, 19, 4) AS TimeBin,
starttime
FROM movement) t) tt
INNER JOIN input.track tr
ON tr.trackid = tt.trackid
AND tr.scenariopid = tt.scenariopid)
SELECT *
FROM casttable
ORDER BY legid,
sequence
OPTION (maxrecursion 20000)
答案 0 :(得分:0)
使用Numbers Table(以下从零开始假定)创建CTE 移动,如下所示:
WITH movement
AS (SELECT m.scenariopid,
m.legid,
Substring(routedata, n.N*23 + 1, 23) AS RoutePart,
n.N AS cnt,
-- 1 AS sequence, -- use a row_number function here instead, as per your vendor.
m.starttime
FROM output.movement m
JOIN Numbers n
on n < Len(routedata) / 23
WHERE scenariopid = @scenario1
AND m.starttime BETWEEN ( @DAY_START * 86400 ) AND
( @DAY_END * 86400 )
),
-- etc.
如果您没有静态数字表,my answer here将演示如何在CTE中动态创建数字表。