Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Ускорить запрос, где count partition by.  [new]
user89
Member

Откуда:
Сообщений: 2083
Здравствуйте! Есть таблица с такой структурой, примерно такого содержания:
Proj_UIDRes_UIDindicatorval
68C588EC-4796-415C-9498-00A1B7DD3275DD6FD47C-2E8C-428A-B923-AC5B37C77412функцияbbbb
68C588EC-4796-415C-9498-00A1B7DD3275DD6FD47C-2E8C-428A-B923-AC5B37C77412функцияabcd
68C588EC-4796-415C-9498-00A1B7DD3275DD6FD47C-2E8C-428A-B923-AC5B37C77412функцияbbbb
68C588EC-4796-415C-9498-00A1B7DD3275DD6FD47C-2E8C-428A-B923-AC5B37C77412функцияabcd

Необходимо получить счетчик:
Proj_UIDRes_UIDindicatorvalcnt
68C588EC-4796-415C-9498-00A1B7DD32755BB199D2-4EF5-4D3F-AC58-300ADC5C6730рольaaaa1
68C588EC-4796-415C-9498-00A1B7DD3275DD6FD47C-2E8C-428A-B923-AC5B37C77412рольffbb1
68C588EC-4796-415C-9498-00A1B7DD3275DD6FD47C-2E8C-428A-B923-AC5B37C77412функцияbbbb2
68C588EC-4796-415C-9498-00A1B7DD3275DD6FD47C-2E8C-428A-B923-AC5B37C77412функцияabcd2

Это делается легко через
select *, count(Proj_UID) over (partition by Proj_UID, Res_UID, indicator) [cnt]
from #t

На больших данных
count(Proj_UID) over (partition by Proj_UID, Res_UID, indicator)
выполняется долго.

Пробовал так
create nonclustered index ix on #t (Proj_UID) include(Res_UID, indicator, val)
и так
create clustered index ix on #t (Proj_UID, Res_UID, indicator, val)

Ускорения нет :(

Какие еще есть способы?

Microsoft SQL Server 2008 R2
Сами данные:
create table #t (Proj_UID uniqueidentifier, Res_UID uniqueidentifier, indicator varchar(50), val varchar(50))
insert #t
  select '68C588EC-4796-415C-9498-00A1B7DD3275', '5BB199D2-4EF5-4D3F-AC58-300ADC5C6730', 'роль', 'aaaa' union all
  select '68C588EC-4796-415C-9498-00A1B7DD3275', 'DD6FD47C-2E8C-428A-B923-AC5B37C77412', 'роль', 'ffbb' union all
  select '68C588EC-4796-415C-9498-00A1B7DD3275', 'DD6FD47C-2E8C-428A-B923-AC5B37C77412', 'функция', 'bbbb' union all
  select '68C588EC-4796-415C-9498-00A1B7DD3275', 'DD6FD47C-2E8C-428A-B923-AC5B37C77412', 'функция', 'abcd'

;with cte as (select *, 1 [cnt] from #t union all select Proj_UID, newid(), indicator, val, cnt+1 from cte where cnt < 5000)
insert #t select Proj_UID, Res_UID, indicator, val from cte option (maxrecursion 0)

declare @t datetime = getdate()

select Proj_UID, Res_UID, indicator, val,
count(Proj_UID) over (partition by Proj_UID, Res_UID, indicator) [cnt]
from #t

select datediff(ms, @t, getdate())

drop table #t
18 июн 12, 18:09    [12733925]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить запрос, где count partition by.  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Сделать таблицу в которой хранить уже рассчитанные данные. Поддерживать при модификации основной.
18 июн 12, 18:11    [12733939]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить запрос, где count partition by.  [new]
user89
Member

Откуда:
Сообщений: 2083
Скопипастил не то... Начальные данные, конечно, выглядят так:
Proj_UIDRes_UIDindicatorval
68C588EC-4796-415C-9498-00A1B7DD32755BB199D2-4EF5-4D3F-AC58-300ADC5C6730рольaaaa
68C588EC-4796-415C-9498-00A1B7DD3275DD6FD47C-2E8C-428A-B923-AC5B37C77412рольffbb
68C588EC-4796-415C-9498-00A1B7DD3275DD6FD47C-2E8C-428A-B923-AC5B37C77412функцияbbbb
68C588EC-4796-415C-9498-00A1B7DD3275DD6FD47C-2E8C-428A-B923-AC5B37C77412функцияabcd
18 июн 12, 18:11    [12733944]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить запрос, где count partition by.  [new]
user89
Member

Откуда:
Сообщений: 2083
Гавриленко Сергей Алексеевич,
спасибо. Наверное так и сделаю.
Просто я думал, что есть какие-нибудь хитрые приемы с cross apply, табличными подсказками и т.д.
18 июн 12, 18:17    [12733974]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить запрос, где count partition by.  [new]
Klopovnik
Member

Откуда: Рига
Сообщений: 39
user89,

я не уверен, но мало ли, если есть возможность попробуйте индексированные вьюшни с вычислениями,
индекс на вью создаст таблицу и поидее будет все тоже самое, что советом выше, только не надо будет думать о поддержке таблицы.
18 июн 12, 20:16    [12734406]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить запрос, где count partition by.  [new]
aleks2
Guest
select T.*
from #t T inner join (select  count(*) [cnt]  from #t group by by Proj_UID, Res_UID, indicator)  x
on T.Proj_UID=X.Proj_UID and T.Res_UID=X.Res_UID and T.indicator=X.indicator


если select count(*) [cnt] from #t group by by Proj_UID, Res_UID, indicator) засунуть во времянку с индексом - будет ишо быстрее.
19 июн 12, 07:45    [12735649]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить запрос, где count partition by.  [new]
aleks2
Guest
Пардон

select T.*
from #t T inner join (select Proj_UID, Res_UID, indicator, count(*) [cnt]  from #t group by by Proj_UID, Res_UID, indicator)  x
on T.Proj_UID=X.Proj_UID and T.Res_UID=X.Res_UID and T.indicator=X.indicator
19 июн 12, 08:18    [12735683]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить запрос, где count partition by.  [new]
user89
Member

Откуда:
Сообщений: 2083
aleks2,

спасибо за вариант, время выборки уменьшилось почти в 2 раза!
19 июн 12, 08:35    [12735703]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить