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

Откуда: Екатеринбург
Сообщений: 21
Всем привет.

В процедуру передается 3 параметра: 2 типа date и 1 типа uniqueidentifier.
Выполняется просто select с подстановкой этих параметров очень долго.

Тот же запрос просто в Management Studio с конкретно указанными параметрами (теми же самыми, что и передаются в процедуру) выполняется почти мгновенно.

Сравнила планы - они разные. Почему? Видимо из-за этого и тормозит. Как "заставить" селект в процедуре использовать тот же план?
27 окт 11, 08:18    [11506460]     Ответить | Цитировать Сообщить модератору
 Re: Разные планы select в процедуре и просто  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
GO,

Используйте option (keepfixed plan)
27 окт 11, 08:21    [11506467]     Ответить | Цитировать Сообщить модератору
 Re: Разные планы select в процедуре и просто  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
https://www.sql.ru/articles/mssql/2005/070704TechniqueForEnsuringPlanStabilityInSQLServer2000.shtml
27 окт 11, 08:31    [11506482]     Ответить | Цитировать Сообщить модератору
 Re: Разные планы select в процедуре и просто  [new]
GO
Member

Откуда: Екатеринбург
Сообщений: 21
Спасибо! Сделала вариант второй, т.к. добавляется еще инсерт.
27 окт 11, 10:23    [11506888]     Ответить | Цитировать Сообщить модератору
 Re: Разные планы select в процедуре и просто  [new]
GO
Member

Откуда: Екатеринбург
Сообщений: 21
И все-таки план разный, если выдернуть запрос и отдельно выполнить (более оптимальный).
Что не так делаю (((?


ALTER PROCEDURE [dbo].[p_proc] ( @Uid uniqueidentifier
, @Date1 date
, @Date2 date
, @Temp_Uid uniqueidentifier = '46A6BC4F-0457-4D44-8483-B8752D840F82'
, @Temp_Date1 date = '2011-09-01'
, @Temp_Date2 date = '2011-09-30'
)

AS
BEGIN

SET NOCOUNT ON;

SET @Temp_Uid = @DUid;
SET @Temp_Date1 = @Date1;
@Temp_Date2 = @Date2;


select fields
from table
where [date] between @Temp_Date1 and @Temp_Date2
and [Uid] = @Temp_Uid

END
27 окт 11, 11:22    [11507402]     Ответить | Цитировать Сообщить модератору
 Re: Разные планы select в процедуре и просто  [new]
iljy
Member

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

потому что отдельно он выполняется под конкретные значения параметров, естественно так возможностей оптимизации больше. Если настолько критично - добавьте к запросу option(recompile).
27 окт 11, 11:32    [11507481]     Ответить | Цитировать Сообщить модератору
 Re: Разные планы select в процедуре и просто  [new]
GO
Member

Откуда: Екатеринбург
Сообщений: 21
tpg
https://www.sql.ru/articles/mssql/2005/070704TechniqueForEnsuringPlanStabilityInSQLServer2000.shtml


А разве по этой методике не получаются как раз конкретные значения:

"Эта методика работает, потому что оптимизатор не может учесть повторное присваивание @country значения @template_country в процессе компиляции. Для оптимизатора, во время планирования инструкции SELECT, @template_country будет всегда иметь значение "США"."
То есть в моем случае должны подставляться конкретные значения, как раз те, с которыми я выполняю селект отдельно.
27 окт 11, 11:47    [11507608]     Ответить | Цитировать Сообщить модератору
 Re: Разные планы select в процедуре и просто  [new]
iljy
Member

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

нет. Параметризованный запрос компилируется для универсального случая, он может оптимизироваться под предполагаемые значения параметров. Посмотрите планы:
use tempdb

create table ttt(id int, val char(100))

insert ttt values (1,'asdkfjhdf')

insert ttt
select top 2000 2, 'adfkjahdsfjsdhf'
from master..spt_values v1,master..spt_values v2

create index IX_ttt on ttt(id)
go
declare @p int = 1

select * from ttt where id = 1


select * from ttt where id = 2

select * from ttt where id = @p


select * from ttt where id = @p option(optimize for (@p=1))
go
drop table ttt
27 окт 11, 11:54    [11507670]     Ответить | Цитировать Сообщить модератору
 Re: Разные планы select в процедуре и просто  [new]
iljy
Member

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

еще более показательны планы таких запросов:
declare @p int = 1

select * from ttt where 1=0

select * from ttt where 0 = @p

select * from ttt where 0 = @p option(optimize for (@p=1))
27 окт 11, 11:56    [11507691]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить