powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Ускоряющая денормализация
24 сообщений из 24, страница 1 из 1
Ускоряющая денормализация
    #39558809
Itille
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Простой пример.
Имеется 2 таблицы, 1 ко многим
T1
Id1 int primary key
N1 varchar(500)

T2
Id2 int primary key
Id1 int
Data datetime
Rekv1, Rekv2 и т.д.

На момент времени @Data1 необходимо иметь значения реквизитов T2 для всех ID по таблице T1

В лоб, без денормализации, это решается UDF с 3 Join T2 самой на себя

Select * from T2 T JOIN
(Select Id1, Max(Id2) as Id2
from T2 A JOIN
( Select Id1, Max(Data) as Data from T2 Where Data < @Data1 Group by id1) B On A.Id1 = B.Id1 and A.Data = B.Data)
group by A.Id2
)M On T.Id1 = M.Id1 and T.Id2 = M.Id2

с индексом по T2: Id1 + Data

Пример - договора и доп. соглашения.

При большом количестве данных нагрузка может быть значительна.
Может, у кого-нибудь есть альтернативные реализации структуры, пусть и ненормализованные?
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39558824
WarAnt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Itille,

Для какой версии сиквела?
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39558829
Itille
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MS SQL 2012. Но если есть в 2016, то расскажите или киньте ссылку, лишним не будет.
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39558831
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Itille,
Код: sql
1.
select top(1) with ties * from T2 where Data < @Data1 order by ROW_NUMBER() over(partition by Id1 order by Data desc) asc
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39558834
WarAnt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ItilleMS SQL 2012. Но если есть в 2016, то расскажите или киньте ссылку, лишним не будет.

тогда изайте LAST_VALUE
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39558854
Itille
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
buser, спасибо!
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39559047
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Itille,

без сортировки, похоже, не обойтись. Если селективность запроса низкая, т.е. T1 содержит большой объем данных, то Вам поможет только прокачка "железа".
Кластерный индекс по t2.Data тоже бы помог, но это не подходит, судя по структуре.

Попробуйте составить календарь заранее просчитать суммы на каждый день (та самая "денормализация"). Отчет летать будет.
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565048
Itille
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
buser, посмотрел, немного не так, правильно:

select top(1) with ties * from T2 where Data < @Data1 order by ROW_NUMBER() over(partition by Id1 order by Data desc, Id2 desc) asc

в Вашем запросе не учтена возможность 2 записей с одинаковой датой.
Всё равно, спасибо!
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565079
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Itillebuser, посмотрел, немного не так, правильно:

select top(1) with ties * from T2 where Data < @Data1 order by ROW_NUMBER() over(partition by Id1 order by Data desc, Id2 desc) asc

в Вашем запросе не учтена возможность 2 записей с одинаковой датой.
Всё равно, спасибо!А в вашем учтена, да?
Думаю, вам надо заменить ROW_NUMBER() на RANK()
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565139
Itille
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iap, согласен,что не указал, что ID2 identity(1б1)
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565143
Itille
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iap,p, согласен,что не указал, что ID2 identity(1,1)

Кстати, поигрался на реальных данных, есть ощущение, что конструкция из 3 join работает несколько быстрее...
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565451
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Itille, да, очень даже может быть... а вот еще вопрос - назачем Max(Id2) в купе с Max(Data)? БардачЁк в данных или бизнеспроцессах? Или просто перестраховка?
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565500
982183
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ItilleНа момент времени @Data1 необходимо иметь значения реквизитов T2 для всех ID по таблице T1

А зачем нам в данном случае T1?
Там нет интересующих вас данных.
Почему нельзя взять ID из T2.Id1
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565501
982183
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дошло. "Доп соглашений" может и не быть...
Но в Т1 нет и даты...
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565522
982183
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всё. Совсем дошло.
Вывести все допсоглашения по всем договорам в которых есть допсоглашения до @Data1
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565524
982183
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В качестве ненормализованного бреда.
Заведи в T1 дополнительное поле "Дата последнего допсоглашения"
И получится один Update и один Select c одним join
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565543
Itille
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
buser, данные ведутся от царя гороха, плюс пользователи бывают замечательные, есть ограничения на редактирование записей ( в течение суток от создания), после чего вменяется для корректировки создавать новую запись.
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565560
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Select * 
   from T2 T 
   JOIN (Select Id1, Max(Id2) as Id2 
           from T2 A 
                JOIN ( Select Id1, Max(Data) as Data from T2 Where Data < @Data1 Group by id1) B On A.Id1 = B.Id1 and A.Data = B.Data)
           group by A.Id2 ) M On T.Id1 = M.Id1 and T.Id2 = M.Id2

-- эквивалент
Select m.* 
   from ( select distinct Id1, Id2 from T2 ) as T 
   cross apply ( select top(1) * from T2 Where Data < @Data1 and Id1 = T.Id1 and Id2 = T.Id2 order by Data desc, Id2 desc ) as m

-- из которого видно, насколько идиотичен исходный запрос (обработка ВСЕЙ таблицы, когда реально надо только часть )
-- для ускорения 
-- select distinct Id1, Id2 from T2 
-- можно материализовать (Indexed View)
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39565984
Itille
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222, во - первых, Ваш запрос неправильный.

Правильно -

Select m.*
from ( select distinct Id1 from T2 ) as T
cross apply ( select top(1) * from T2 Where Data < @Data1 and Id1 = T.Id1 order by Data desc, Id2 desc ) as m

А во-вторых, мне не очень нравится order by внутри функции.

Вариант buser больше по душе
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39566013
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Itillealeks222, во - первых, Ваш запрос неправильный.

Правильно -

Select m.*
from ( select distinct Id1 from T2 ) as T
cross apply ( select top(1) * from T2 Where Data < @Data1 and Id1 = T.Id1 order by Data desc, Id2 desc ) as m

А во-вторых, мне не очень нравится order by внутри функции.

Вариант buser больше по душеВнутри какой-такой функции?

Вижу не ORDER BY, а TOP(1) ... ORDER BY.
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39566025
Cammomile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WarAntItilleMS SQL 2012. Но если есть в 2016, то расскажите или киньте ссылку, лишним не будет.

тогда изайте LAST_VALUE

А оно быстрее аплая с TOP (1) ORDER... DESC ?

Ни разу не пользовался такой штукой.
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39566032
Itille
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iap, я имел в виду подзапрос.

Сейчас поэксперементировал.
Могу сказать, что на реальных данных время выполнения хуже, чем даже у запроса в первом посте.
Где-то в 2-3 раза на 1 млн. записей.
Но это на конкретном массиве записей с конкретными значениями.
В принципе, сам вариант имеет право на существование.
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39566039
Itille
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
На самом деле, есть подозрение, что все вышеприведенные варианты по эффективности зависят от среднего количества строк в таблице t2 на каждое значение t1.
Вышенаписанное (в предыдущем моем топике) верно для среднего значения около 2.
...
Рейтинг: 0 / 0
Ускоряющая денормализация
    #39566145
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Itillealeks222, во - первых, Ваш запрос неправильный.

Правильно -

Select m.*
from ( select distinct Id1 from T2 ) as T
cross apply ( select top(1) * from T2 Where Data < @Data1 and Id1 = T.Id1 order by Data desc, Id2 desc ) as m

А во-вторых, мне не очень нравится order by внутри функции.

Вариант buser больше по душе

Дык, страдалец, ты меня пугаешь своей замороченностью.

Код: sql
1.
2.
3.
Select m.* 
   from T1 as T 
   cross apply ( select top(1) * from T2 Where Data < @Data1 and Id1 = T.Id1 order by Data desc, Id2 desc ) as m


+ индекс T2(Id1, Data, Id2)
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Ускоряющая денормализация
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]