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

Откуда: http://city-afisha.com
Сообщений: 692
Всем привет!

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

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 мин работает Оо.... сижу, курю.... но так долго вообще не подходит, данных будет много...

можно как то оптимизировать курсор или переписать без курсора?
30 апр 15, 10:06    [17585202]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Glory
Member

Откуда:
Сообщений: 104751
Sputnick
можно как то оптимизировать курсор

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

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

Т.е. нужно придумать задачу под ваш "курсор" ?
30 апр 15, 10:09    [17585233]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Sputnick
Member

Откуда: http://city-afisha.com
Сообщений: 692
Glory
Sputnick
можно как то оптимизировать курсор

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

от open curs до close curs


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

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


может можно сделать эти апдейты без применения курсора....
30 апр 15, 10:14    [17585264]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Glory
Member

Откуда:
Сообщений: 104751
Sputnick
может можно сделать эти апдейты без применения курсора....

Ну так делайте. Кто/что вам мешает ?
30 апр 15, 10:15    [17585266]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Sputnick
Member

Откуда: http://city-afisha.com
Сообщений: 692
Glory
Sputnick
может можно сделать эти апдейты без применения курсора....

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


не мог, поэтому сделал ка мог - курсором. На маленькой таблице еще норм, а на большой не подходит.
30 апр 15, 10:19    [17585293]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Glory
Member

Откуда:
Сообщений: 104751
Sputnick
не мог, поэтому сделал ка мог - курсором. На маленькой таблице еще норм, а на большой не подходит.

И что вы предлагаете сделать ?
Подъехать к вам и в личной беседе заставить вас сделать постановку задачи ?
30 апр 15, 10:20    [17585308]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Sputnick
Glory
пропущено...

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

от open curs до close curs


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

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


может можно сделать эти апдейты без применения курсора....
Почему Вы о нём во множественном числе?
30 апр 15, 10:23    [17585331]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
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


Что-то типа такого должно работать. Но не факт, чтобы будет наиболее оптимально выполняться, поскольку Вы не привели ни структуры таблиц, ни какие индексы и тд.
30 апр 15, 10:25    [17585338]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Sputnick
Member

Откуда: http://city-afisha.com
Сообщений: 692
[quot AlanDenton]
 
OUTER APPLY (
	 
) t2


не знал этого оператора, спасибо попробую в эту сторону
30 апр 15, 10:26    [17585350]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Ну смысл будет такой же и с 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


А вот планы выполнения могут отличаться. В общем пробуйте. Вроде нигде не ошибся.
30 апр 15, 10:30    [17585381]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
В последнем запросе забыл дописать

	WHERE b.endd = '20150430' OR b.beginn ='20150401'
	GROUP BY c.ls


вместе

	WHERE b.endd = '20150430' OR b.beginn ='20150401'
30 апр 15, 10:40    [17585496]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Sputnick
Member

Откуда: http://city-afisha.com
Сообщений: 692
AlanDenton
В последнем запросе забыл дописать
вместе


спасибо, жду пока курсор отработает, и пробую ваш вариант.
30 апр 15, 10:46    [17585557]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
А что мешает залить данные в новую таблицу:

SELECT *
INTO dbo.file_in_new
FROM dbo.file_in


Навесить на нее все индексы что были у dbo.file_in и сравнить перформанс.
30 апр 15, 10:50    [17585588]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Sputnick
Member

Откуда: http://city-afisha.com
Сообщений: 692
AlanDenton
А что мешает залить данные в новую таблицу:

SELECT *
INTO dbo.file_in_new
FROM dbo.file_in


Навесить на нее все индексы что были у dbo.file_in и сравнить перформанс.


мизер доступного времени на эту задачу, мне ее нужно быстро сделать и дальше идти, скул это моя не основная задача, поэтому не силен в нем (
30 апр 15, 11:06    [17585728]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Sputnick
Member

Откуда: http://city-afisha.com
Сообщений: 692
AlanDenton
[src]

Что-то типа такого должно работать. Но не факт, чтобы будет наиболее оптимально выполняться


с джойном не получилось, а вот этот вариант отработал на ура - 2 секунды!

Спасибо огромное, сэкономили время и нервы )

киньте WM или киви кошелек кинуть на prokomputers @ gmail.com перешлю благодарность
30 апр 15, 13:24    [17586825]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Рад был помочь. По поводу кошельков и прочего - это лишнее. "Не корысти ради" я здесь зарегистрировался. :)

А вот по поводу LEFT JOIN стало интересно - что не так?
30 апр 15, 13:40    [17586959]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Sputnick
Member

Откуда: http://city-afisha.com
Сообщений: 692
AlanDenton
что не так?


я ради безопасности имена табл и полей поменял конечно все, еле в принципе заставил его выполняться, просто не апдейтил, писал затронуто строк -1, но подзапрос данные выбирал:

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'


Я проверил.
Ну и сразу попробовал первый вариант - отработал.
30 апр 15, 13:55    [17587035]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Если честно, не совсем понял, почему LEFT JOIN не подошел. Между этими двумя запросами должна быть существенная разница - все зависит от распределения данных. Первый должен содержать Index Seek-и, а второй делать один большой - Index Scan по таблице bal. Сложно сказать о чем-то не видя планов выполнения запросов.

Впрочем, если OUTER APPLY Вам подошел. Почему бы и нет. Хорошего Вам дня.
30 апр 15, 14:03    [17587085]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Sputnick
Member

Откуда: http://city-afisha.com
Сообщений: 692
AlanDenton
Сложно сказать о чем-то не видя планов выполнения запросов.
. Почему бы и нет. Хорошего Вам дня.


там 2 таблицы с разных баз.... мало ли какие там еще нюансы....

Спасибо, взаимно, редко таких людей как вы встретишь ) Всё влияет на всё. В этой вселенной, когда изменяется одна вещь, меняется всё. Отсюда и великая сила человека менять мир, изменяя себя. оригинал: http://aforizmus.com/aphorism/1552
30 апр 15, 14:11    [17587132]     Ответить | Цитировать Сообщить модератору
 Re: Помогите оптимизировать курсор  [new]
Wilhelm Holtoff
Member

Откуда:
Сообщений: 85
Sputnick
не мог, поэтому сделал как мог - курсором.
вот вот, здесь-то и вся суть.
По-нормальному он не мог, а курсором он смог.
Сам по себе курсор - он противоречит духу языка SQL - основу которого составляют операции над множествами, а не над отдельными записями.
30 апр 15, 14:13    [17587146]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить