![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
долго работает хранимая процедура [MSSQL]
SLP © (2007-01-16 12:02:00)Добрый день!
У меня хранимая процедура на сервере отрабатывает около 5 мин. Помещаю этот же самый запроc в QA и он отрабатывает за 2 сек. Сервер MSSQL2000, SP поставлен последний.
Помогите пожалуйста советом, куда смотреть ?
evvcom (2007-01-16 15:58:00) [61]> [9] Ega23 © (16.01.07 15:54)
> Это так округляется время и берётся предыдущий день
А, ну да... :)))
Только для этого есть спец.функция округления, но ты то знаешь это. Осталось автору это рассказать.
Ega23 (2007-01-16 15:54:00) [62]
> а это зачем? Если данные по сути дата или число не надо
> их хранить в строке! Аналогично с параметрами.
Это так округляется время и берётся предыдущий день.
clickmaker (2007-01-16 15:53:00) [63]
> [6] Desdechado © (16.01.07 15:44)
> а зачем нужна процедура из одного запроса?
а что в этом криминального?
evvcom (2007-01-16 15:50:00) [64]> [5] SLP © (16.01.07 14:40)
> он в среднем на 2 сек дольше
значит оптимизатор нормально разруливал
> Но в любом случае, когда выполняешь его в ХП, все также
> медленно выполняется ХП, порядка 5 мин
значит план другой. Я с MS мало общался, но помню читал как-то советы по этому поводу. Есть в справке такое:
Creating a stored procedure that specifies the WITH RECOMPILE option in its definition ...
может это и не хороший совет (устранение последствий, а не причины), но тем не менее.
> cast(convert(char(10),a.ssd_mail,102) as datetime))
а это зачем? Если данные по сути дата или число не надо их хранить в строке! Аналогично с параметрами.
Desdechado (2007-01-16 15:44:00) [65]а зачем нужна процедура из одного запроса?
SLP (2007-01-16 14:40:00) [66]
> evvcom © (16.01.07 12:25) [4]
Попробовала Ваш запрос в QA.
declare @d_mail datetime,@d_mail2 datetime
set @d_mail='20070101'
set @d_mail2='20070115'
select rtrim(ves.iki_ves)+' '+ rtrim(ves.board_number)+' '+rtrim(ves.ves) as name_ves,
cast(convert(char(10),
a.datetime,102) as datetime) as ssd_data,
datediff(day,a.datetime,cast(convert(char(10),a.ssd_mail,102) as datetime))-1 as day_r,a.id_ssd, a.id_ves, a.ssd_mail
from start_ssd a
left join start_ssd c
on c.id_ves=a.id_ves and
c.datetime=a.datetime and
c.ssd_mail<a.ssd_mail
join ves on a.id_ves=ves.id_ves
where c.id_ves is null
and a.ssd_mail>=@d_mail
and a.ssd_mail<=@d_mail2
and a.processstatus not in (1,11)
and a.mem in (21,31)
and a.id_ves<>0
and datediff(day,a.datetime,a.ssd_mail)>=2
order by a.ssd_data,a.id_ves
Такой запрос, конечно, красивый. Но вот выполняется он в среднем на 2 сек дольше, чем с "and not exists". Мой 5 сек, Ваш - 7 сек. Запускала по очереди порядка 10 раз.
Но в любом случае, когда выполняешь его в ХП, все также медленно выполняется ХП, порядка 5 мин.
evvcom (2007-01-16 12:25:00) [67]> [2] SLP © (16.01.07 12:08)
> from start_ssd a, start_ssd b
> join ves
ты бы уж определился, то ли ты будешь использовать ключевое слово join, то ли не будешь. А так от твоего винегрета подташнивает.
> and not exists
> (select id_ssd
> from start_ssd
по сути получается, если оптимизатор не сможет ЭТОкак то умно переделать, то получится, что для каждого a.id_ves надо серверу выполнить подзапрос, отсюда и тормоза. Попробуй
from start_ssd a
left join start_ssd с
on c.id_ves=a.id_ves and
c.datetime=a.datetime and
c.ssd_mail<a.ssd_mail
where c.id_ves is null
Вместо многократного выполнения подзапроса только join и filter.
stone (2007-01-16 12:19:00) [68]
> SLP © (16.01.07 12:08) [2]
профайле выдаст тебе команду типа sp_execsql и т.д. с параметрами
вот ее и выполни в аналайзере и посмотри палн выполнения
если будут теже проблемы есть еще ряд ньюансов
SLP (2007-01-16 12:08:00) [69]
> на план выполнения запроса и команды в профайлере
Не знаю как в хранимой процедуре смотреть план выполнения запроса и команды...
Вот текст ХР
CREATE PROCEDURE [dbo].[ssd_delayed_period] (@d_mail datetime, @d_mail2 datetime ) AS
------EXEC DBO.SSD_DELAYED '20061205','20061215'
BEGIN
select rtrim(ves.iki_ves)+' '+ rtrim(ves.board_number)+' '+rtrim(ves.ves) as name_ves,cast(convert(char(10),
a.datetime,102) as datetime) as ssd_data,
datediff(day,a.datetime,cast(convert(char(10),a.ssd_mail,102) as datetime))-1 as day_r,a.id_ssd, a.id_ves, a.ssd_mail
from start_ssd a, start_ssd b
join ves on b.id_ves=ves.id_ves
where a.ssd_mail>=@d_mail
and a.ssd_mail<=@d_mail2
and a.id_ssd=b.id_ssd
and a.processstatus not in (1,11)
and a.mem in (21,31)
and a.id_ves<>0
and datediff(day,a.datetime,a.ssd_mail)>=2
and not exists
(select id_ssd
from start_ssd
where id_ves=a.id_ves
and datetime=a.datetime
and ssd_mail<a.ssd_mail)
order by a.ssd_data, a.id_ves
END
GO
stone (2007-01-16 12:03:00) [70]
> Помогите пожалуйста советом, куда смотреть ?
на план выполнения запроса и команды в профайлере