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

Откуда: Киев
Сообщений: 1199
Всем здравствуйте,
Есть
Microsoft SQL Server 2008 SP2 Enterprise Edition на Windows Server 2003 R2 SP2 Enterprise Edition

На сервере база, в которую реплицируются данные из основной БД,
Написан скрипт такого вида:
declare @InAgreeID int; 
select @InAgreeID=0; 
declare CCursor Cursor Local Fast_Forward Read_Only 
for select AgreeID from Agreements where AgreePacket=1 
open CCursor; 
fetch next from CCursor INTO @InAgreeID;
 while @@fetch_status=0 begin 
     --выполняем всякие вычисления
    fetch next from CCursor INTO @InAgreeID; 
   end 
close CCursor;
deallocate CCursor

И все хорошо -9500 записей обрабатывается курсором за 3 секунды.
Но когда пытаюсь применить этот подход в табличной функции, т.е. заполнить результирующую таблицу в курсоре, - начинается странное: за 3 секунды функция успевается обрабоать не 9500 записей, а 5.
Вопрос простой - куда рыть?
Советы, дополнительные вопросы приветствуются.

С уважением, Londinium
27 янв 12, 00:25    [11980278]     Ответить | Цитировать Сообщить модератору
 Re: Курсор в табличной функции  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
londinium
Вопрос простой - куда рыть?
Рыть в сторону "--выполняем всякие вычисления" и ответа на вопрос "а зачем тут курсор вообще?".

Сообщение было отредактировано: 27 янв 12, 00:37
27 янв 12, 00:37    [11980313]     Ответить | Цитировать Сообщить модератору
 Re: Курсор в табличной функции  [new]
1
Guest
Ну а за какое вркмя выполняется SELECT из этой табличной функции?
27 янв 12, 14:29    [11983474]     Ответить | Цитировать Сообщить модератору
 Re: Курсор в табличной функции  [new]
londinium
Member

Откуда: Киев
Сообщений: 1199
автор
Ну а за какое вркмя выполняется SELECT из этой табличной функции?

Мгновенно. Проблема прячется именно в курсоре, который заполняет табличную переменную
27 янв 12, 14:53    [11983755]     Ответить | Цитировать Сообщить модератору
 Re: Курсор в табличной функции  [new]
Glory
Member

Откуда:
Сообщений: 104751
londinium
Проблема прячется именно в курсоре, который заполняет табличную переменную

Т.е. вы тестируете два разных кода что ли ?
27 янв 12, 15:12    [11983930]     Ответить | Цитировать Сообщить модератору
 Re: Курсор в табличной функции  [new]
londinium
Member

Откуда: Киев
Сообщений: 1199
Т.е. вы тестируете два разных кода что ли ?
Не совсем. Код в скрипте заполняет временную таблицу через курсор, затем этот же код оборачивается в табличную функцию.
27 янв 12, 15:54    [11984319]     Ответить | Цитировать Сообщить модератору
 Re: Курсор в табличной функции  [new]
DisAgreeID
Guest
londinium
Т.е. вы тестируете два разных кода что ли ?
Не совсем. Код в скрипте заполняет временную таблицу через курсор, затем этот же код оборачивается в табличную функцию.

профайлер покажет какой код тормозит.
во всяких вычислениях наверно не только вычисления, но и всякие селекты из больших табличек с фильтром по @InAgreeID?
28 янв 12, 15:47    [11989057]     Ответить | Цитировать Сообщить модератору
 Re: Курсор в табличной функции  [new]
Crimean
Member

Откуда:
Сообщений: 13147
обманывать нехорошо :)

пример 1, без функции

set nocount on

declare @dt datetime
set @dt = getdate()

declare @a table ( id int , name sysname )

declare ccc cursor local fast_forward read_only for
select top 9500 
id, name
from sysobjects

open ccc

while 1=1 begin

declare @id int , @name sysname

fetch next from ccc into @id, @name

if @@fetch_status <> 0 break

insert into @a ( id, name ) values( @id , @name )

end

select * from @a

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


пример 2, то же, но внутри функции

set nocount on

drop function dbo.f1
go

create function dbo.f1() returns @a table ( id int , name sysname )
as
begin

declare ccc cursor local fast_forward read_only for
select top 9500 
id, name
from sysobjects

open ccc

while 1=1 begin

declare @id int , @name sysname

fetch next from ccc into @id, @name

if @@fetch_status <> 0 break

insert into @a ( id, name ) values( @id , @name )

end

return 
end
go

declare @dt datetime
set @dt = getdate()

select * from dbo.f1()

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


время выполнения порядка 350 ms в обоих случаях
28 янв 12, 16:42    [11989167]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить