Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 возможна ли оптимизация Self-Join по ключу  [new]
БД_Юзверь
Member

Откуда:
Сообщений: 3
Есть табличные инлайн-функции, которые принимают в параметре дату актуальности и возвращают данные из основной таблицы и соединенных с ней таблиц с периодиками (первичный ключ = первичный ключ основной таблиц + дата).
В общем суть в том, что обращаясь к такой функции и указывая дату мы получаем все необходимые столбцы, не задумываясь о том где именно они хранятся - в основной таблице или периодиках. Довольно удобно и универсально, поскольку не нужно изменять кучу кода в случае если какой-то из столбов станет или не станет периодическим. Нужно будет поправить, только одну функцию.

Иногда возникает необходимость запросить кроме актуальных данных еще и данные из столбца на дату, которая находилась в прошлом. В таком случае приходится делать соединение по первичному ключу (pk_id) этих 2х функций с разными параметрами:
SELECT T1.*, T2.c5
FROM            tabe_inline_func(@date1) AS T1
LEFT OUTER JOIN tabe_inline_func(@date2) AS T2  ON T2.pk_id = T1.pk_id

В плане запроса получается Self-Join основной таблицы самой с собой по первичному ключу. Т.е. если убрать все лишнее получается запрос:
SELECT T1.*, T2.c5
FROM            common_table AS T1
LEFT OUTER JOIN common_table AS T2  ON T2.pk_id = T1.pk_id

Вопрос: неужели sql server не может понять, что в таком запросе осуществляется соединение строки самой с собой и т.о. план запроса можно упростить до примерно такого:
SELECT T1.*, T1.c5
FROM            common_table AS T1

Может быть можно как-то явно указать на необходимость оптимизации?

Избавиться от такого двойного запроса к таблице можно убрав из функции основную таблицу и оставив только периодики, которые будут соединяться по параметру:
SELECT T1.*, T2.c5
FROM       common_table                       AS T1
OUTER JOIN tabe_inline_func(T1.pk_id, @date2) AS T2

Однако при такой схеме мы теряем универсальность запроса и получаем необходимость исправлять каждый раз весь подобный код при смене конфигурации периодик (перемещение столбца в/из периодику).

Получается выбор между универсальностью кода и неоптимальность запросов.
Можно ли как-то избежать компромисса?
3 май 18, 15:17    [21384749]     Ответить | Цитировать Сообщить модератору
 Re: возможна ли оптимизация Self-Join по ключу  [new]
БД_Юзверь
Member

Откуда:
Сообщений: 3
Сервер:
Microsoft SQL Server 2014 (SP2-CU9) (KB4055557) - 12.0.5563.0 (X64)
Dec 7 2017 01:00:06
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)

Клиентское приложение: SSMS v17.6
3 май 18, 15:23    [21384800]     Ответить | Цитировать Сообщить модератору
 Re: возможна ли оптимизация Self-Join по ключу  [new]
БД_Юзверь
Member

Откуда:
Сообщений: 3
Код для получения плана запроса:

DECLARE @common_table TABLE
(
  pk_id Int,
  c1    VarChar(50),
  c2    DateTime2   DEFAULT SysDateTime(),
  c3    Int,
  c4    Bit,
  c5    UniqueIdentifier  DEFAULT NewId(),
  Primary Key (pk_id)
);
INSERT INTO @common_table (pk_id)
 VALUES (1), (2), (3), (4);
SELECT T1.*, T2.c5
FROM              @common_table AS T1
LEFT OUTER JOIN   @common_table AS T2  ON T2.pk_id = T1.pk_id;
3 май 18, 15:43    [21384920]     Ответить | Цитировать Сообщить модератору
 Re: возможна ли оптимизация Self-Join по ключу  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2421
БД_Юзверь,

кнопки "сделай красиво и быстро" нет, если вы об этом.
выбирайте что вам важнее скорость работы или универсальность,
и да, самолет-корабль, всегда хуже самолета и корабля.
3 май 18, 15:49    [21384953]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить