Помогите оптимизировать курсор

Sputnick
Дата: 30.04.2015 10:06:08
Всем привет!

ребят есть вот такой курсор:

set dateformat ymd
 SET NOCOUNT ON
declare @cont_serv int , @ls CHAR(15)
 
declare curs cursor static for
select  d.ls from file_in d   
--открыть курсор и пройти все записи
open curs
fetch next from curs into   @ls  

while @@Fetch_Status=0
begin
 SET NOCOUNT ON  
 
--1
UPDATE file_in SET dolg_1 = (SELECT sum(b.money_vh*100) from db.dbo.bal b where b.contract_service in (select c.cs from cs c where c.ls =  @ls) and b.beginn='2015/4/01')
where ls = @ls

--2
UPDATE file_in SET dolg_2 = (SELECT sum(b.money*100) from db.dbo.bal b where b.contract_service in (select c.cs from cs c where c.ls =  @ls) and b.endd='2015/4/30')
where ls = @ls

               
	
fetch next from curs into  @ls  
end

close curs
deallocate curs


как то запускал его изредка, в file_in было несколько сотен записей, отрабатывал быстро. А сейчас нужно обработать данные, когда их будет по несколько тысяч.... сейчас в табле 8 тыс записей.... курсор уже 30 мин работает Оо.... сижу, курю.... но так долго вообще не подходит, данных будет много...

можно как то оптимизировать курсор или переписать без курсора?
Glory
Дата: 30.04.2015 10:09:31
Sputnick
можно как то оптимизировать курсор

Вы какую из команд вашего скрипта называете "курсором" ?

Sputnick
или переписать без курсора?

Т.е. нужно придумать задачу под ваш "курсор" ?
Sputnick
Дата: 30.04.2015 10:14:58
Glory
Sputnick
можно как то оптимизировать курсор

Вы какую из команд вашего скрипта называете "курсором" ?

от open curs до close curs


Sputnick
или переписать без курсора?

Т.е. нужно придумать задачу под ваш "курсор" ?


может можно сделать эти апдейты без применения курсора....
Glory
Дата: 30.04.2015 10:15:20
Sputnick
может можно сделать эти апдейты без применения курсора....

Ну так делайте. Кто/что вам мешает ?
Sputnick
Дата: 30.04.2015 10:19:11
Glory
Sputnick
может можно сделать эти апдейты без применения курсора....

Ну так делайте. Кто/что вам мешает ?


не мог, поэтому сделал ка мог - курсором. На маленькой таблице еще норм, а на большой не подходит.
Glory
Дата: 30.04.2015 10:20:53
Sputnick
не мог, поэтому сделал ка мог - курсором. На маленькой таблице еще норм, а на большой не подходит.

И что вы предлагаете сделать ?
Подъехать к вам и в личной беседе заставить вас сделать постановку задачи ?
iap
Дата: 30.04.2015 10:23:33
Sputnick
Glory
пропущено...

Вы какую из команд вашего скрипта называете "курсором" ?

от open curs до close curs


пропущено...

Т.е. нужно придумать задачу под ваш "курсор" ?


может можно сделать эти апдейты без применения курсора....
Почему Вы о нём во множественном числе?
AlanDenton
Дата: 30.04.2015 10:25:02
UPDATE f
SET 
	  dolg_1 = ISNULL(t2.value1, 0)
	, dolg_2 = ISNULL(t2.value2, 0)
FROM dbo.file_in f
OUTER APPLY (
	SELECT
		  value1 = SUM(CASE WHEN b.beginn ='20150401' THEN b.money_vh * 100 END)
		, value2 = SUM(CASE WHEN b.endd = '20150430' THEN b.[money] * 100 END)
	FROM dbo.bal b
	JOIN dbo.cs c ON b.contract_service = c.cs
	WHERE c.ls = f.ls and (b.endd = '20150430' OR b.beginn ='20150401')
) t2


Что-то типа такого должно работать. Но не факт, чтобы будет наиболее оптимально выполняться, поскольку Вы не привели ни структуры таблиц, ни какие индексы и тд.
Sputnick
Дата: 30.04.2015 10:26:42
[quot AlanDenton]
 
OUTER APPLY (
	 
) t2


не знал этого оператора, спасибо попробую в эту сторону
AlanDenton
Дата: 30.04.2015 10:30:01
Ну смысл будет такой же и с LEFT JOIN

UPDATE f
SET 
	  dolg_1 = ISNULL(t2.value1, 0)
	, dolg_2 = ISNULL(t2.value2, 0)
FROM dbo.file_in f
LEFT JOIN (
	SELECT
		  c.ls
		, value1 = SUM(CASE WHEN b.beginn ='20150401' THEN b.money_vh * 100 END)
		, value2 = SUM(CASE WHEN b.endd = '20150430' THEN b.[money] * 100 END)
	FROM dbo.bal b
	JOIN dbo.cs c ON b.contract_service = c.cs
	WHERE b.endd = '20150430' OR b.beginn ='20150401'
) c ON c.ls = f.ls


А вот планы выполнения могут отличаться. В общем пробуйте. Вроде нигде не ошибся.