我每天(过夜)运行以下查询,并且需要相当长的时间才能运行(1-1.5小时)。我确定" Acc.DateKey> = LEFT(LocationKey,8)"是原因,如果连接的这部分被删除,查询将在大约5分钟内执行。我想不出更有效的方式。
Acc.DateKey通常是20180101等,其中位置键通常为201801011234等。
到目前为止,我已经考虑在LO表格中添加一个新列" AccLocationKey"在加载时将使用LEFT(LocationKey,8)函数插入。
我已经决定先在这里提出问题 - 如果不改变LO表,可以改进吗?
SELECT
ISNULL(MAX(L.LocationKey),(SELECT MIN(LocationKey) FROM LO WHERE Location = Acc.Location)) AS LocationKey
FROM
Acc
LEFT OUTER JOIN
(
SELECT
LocationKey
,Location
FROM
LO
)AS L
ON Acc.Location = L.Location AND Acc.DateKey >= LEFT(LocationKey,8)
答案 0 :(得分:0)
让我们在SELECT
:
SELECT COALESCE(MAX(L.LocationKey), MIN(L.MIN_LocationKey)) AS LocationKey
FROM Acc LEFT OUTER JOIN
(SELECT MIN(l.LocationKey) OVER (PARTITION BY l.Location) as min_location,
l.*
FROM LO l
) L
ON Acc.Location = L.Location AND Acc.DateKey >= LEFT(l.LocationKey, 8);
可能性能最佳的机会是添加计算列和适当的索引。所以:
alter table lo add locationkey_datekey as (try_convert(bigint, LEFT(l.LocationKey, 8))) persisted;
然后,适当的索引:
create index idx_lo_location_datekey on lo(location, locationkey_datekey);
然后在查询中使用它:
SELECT COALESCE(MAX(L.LocationKey), MIN(L.MIN_LocationKey)) AS LocationKey
FROM Acc LEFT OUTER JOIN
(SELECT MIN(l.LocationKey) OVER (PARTITION BY l.Location) as min_location,
l.*
FROM LO l
) L
ON Acc.Location = L.Location AND Acc.DateKey >= l.LocationKey_datekey;
令人高兴的是,这个索引也适用于窗口函数。