Левое внешнее соединение с функцией left () - PullRequest
0 голосов
/ 08 июня 2018

Я выполняю приведенный ниже запрос ежедневно (в одночасье), и для его выполнения требуется значительное время (1-1,5 часа).Я уверен, что «Acc.DateKey> = LEFT (LocationKey, 8)» является причиной, и если эта часть объединения удаляется, запрос выполняется примерно через 5 минут.Я просто не могу придумать более эффективный способ.

Acc.DateKey - это bigint, как правило, 20180101 и т. Д., А ключ местоположения - это bigint, как правило, 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)

1 Ответ

0 голосов
/ 08 июня 2018

Давайте перепишем запрос без подзапроса в 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;

К счастью, этот индекс также будет работать дляоконная функция.

...