Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Кэширование результатов запроса CTE  [new]
rere1234
Member

Откуда:
Сообщений: 38
Доброе время суток уважаемые форумчане,
сейчас занимаюсь изучением возможностей языка T-SQL и натолкнулся на небольшую проблему

Диспозиция:

Информация select @@VERSION
+
Microsoft SQL Server 2012 - 11.0.5058.0 (X64)
May 14 2014 18:34:29
Copyright (c) Microsoft Corporation
Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)



Есть две таблицы, одна 10 строчек, вторая около 16 млн. Код по созданию представлен ниже

if OBJECT_ID('#data') is not null
	drop table #data
go

if OBJECT_ID('#type') is not null
	drop table #type
go

create table #type (id int identity primary key, name char(100))
go

insert into #type(name) values (newid())
go 10

with s1(id) as (select 1 union all select 1),
	 s2(id) as (select a.id from s1 a cross join s1),
	 s3(id) as (select a.id from s2 a cross join s2),
	 s4(id) as (select a.id from s3 a cross join s3),
	 s5(id) as (select a.id from s4 a cross join s4),
	 s6(id) as (select a.id from s5 a cross join s4)
select id = identity(int, 1, 1), cast(newid() as char(100)) name, 
		(select top(1) id from #type order by newid()) as idgroup into #data 
from s6



Проблема заключается в том, что долго отрабатывает запрос представленный ниже

with wdata(count, idgroup) as (select count(1), idgroup from #data group by idgroup)
select * from wdata
where idgroup = 1
union all
select * from wdata
where idgroup in (2, 3)
union all
select * from wdata
where idgroup in (1, 2, 3)
union all
select * from wdata
where idgroup in (4, 5)
union all
select * from wdata
where idgroup in (6, 7, 8, 9, 0)


как я понимаю причина в том, что для каждого из select запроса по таблице wdata происходит вычисление агрегатов по #data. Как можно избежать этого? есть ли возможность вычислить один раз результат wdata и использовать его для фильтрации по полю idgroup.
12 янв 15, 11:47    [17105003]     Ответить | Цитировать Сообщить модератору
 Re: Кэширование результатов запроса CTE  [new]
Glory
Member

Откуда:
Сообщений: 104751
rere1234
как я понимаю причина в том, что для каждого из select запроса по таблице wdata происходит вычисление агрегатов по #data.

Это вы план выполнения пересказываете ?

rere1234
Как можно избежать этого? есть ли возможность вычислить один раз результат wdata и использовать его для фильтрации по полю idgroup.

Ну так помещяете результат CTE в таблицу
12 янв 15, 11:53    [17105053]     Ответить | Цитировать Сообщить модератору
 Re: Кэширование результатов запроса CTE  [new]
Владислав Колосов
Member

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

В Вашем запросе оптимизатор группировку игнорирует. т.к. она ничего не группирует на самом деле.
12 янв 15, 12:05    [17105152]     Ответить | Цитировать Сообщить модератору
 Re: Кэширование результатов запроса CTE  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8353
А, нет, ошибся. Посмотрел план - действительно вычисляется агрегат для каждого.
12 янв 15, 12:09    [17105169]     Ответить | Цитировать Сообщить модератору
 Re: Кэширование результатов запроса CTE  [new]
_djХомяГ
Guest
Так, как сказали выше, сделайте группироаку по полю idgroup из оригинальной таблицы #data и положите резултат в табличную переменную/временную таблицу И затем уже начитывайте итоги из нее
12 янв 15, 12:12    [17105188]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить