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

Откуда: Москва, Ясенево
Сообщений: 139
Table Users
(
id int PRIMARY KEY,
total_credit decimal(28,2),
rank int
)

Надо всех ранжировать по total_credit и записать rank.
Операция простая, но у меня выполняется последовательно простейшим курсором.

declare @id int
declare @rank int = 0

declare user_cursor cursor local static forward_only for
select id from dbo.Users order by total_credit desc

open user_cursor
fetch from user_cursor into @id

while @@FETCH_STATUS=0
BEGIN
	set @rank=@rank+1
	update dbo.Users set rank=@rank where id=@id
   fetch next from user_cursor into @id
END
close user_cursor deallocate user_cursor 


Загрузка процессоров - никакая. SQL сервер лениво перебирает участников..
в общем, душераздирающее зрелище, продолжающееся 20 минут.
(участников - 2,5 миллиона).

Нельзя ли это как-то ускорить ?
12 авг 12, 21:13    [13001177]     Ответить | Цитировать Сообщить модератору
 Re: Как ускорить вычисление рангов ?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37050
Зачем тут курсор? O_o
12 авг 12, 21:15    [13001186]     Ответить | Цитировать Сообщить модератору
 Re: Как ускорить вычисление рангов ?  [new]
SerVal
Member

Откуда: Москва, Ясенево
Сообщений: 139
Гавриленко Сергей Алексеевич
Зачем тут курсор? O_o


Затем, что по-другому не умею. Вот и спрашиваю.
Курсор-то, по крайней мере, дело делает.
12 авг 12, 21:38    [13001273]     Ответить | Цитировать Сообщить модератору
 Re: Как ускорить вычисление рангов ?  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
SerVal
Гавриленко Сергей Алексеевич
Зачем тут курсор? O_o


Затем, что по-другому не умею. Вот и спрашиваю.
Курсор-то, по крайней мере, дело делает.
RANK() OVER()
DENSE_RANK() OVER()
???
12 авг 12, 21:52    [13001321]     Ответить | Цитировать Сообщить модератору
 Re: Как ускорить вычисление рангов ?  [new]
SerVal
Member

Откуда: Москва, Ясенево
Сообщений: 139
iap, спасибо, но что-то я никак не догадаюсь, как при помощи этих RANK() OVER() обновить ранги. :(
12 авг 12, 22:06    [13001363]     Ответить | Цитировать Сообщить модератору
 Re: Как ускорить вычисление рангов ?  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
SerVal
iap, спасибо, но что-то я никак не догадаюсь, как при помощи этих RANK() OVER() обновить ранги. :(
WITH CTE AS (SELECT [rank], r=DENSE_RANK() OVER(ORDER BY [total_credit] DESC) FROM [Users])
UPDATE CTE SET [rank] = r;
Бросается в глаза отсутствие WHERE.
Надо проапдейтить всю-всю таблицу [Users], да?!
Вообще-то, это большой грех!
12 авг 12, 22:22    [13001407]     Ответить | Цитировать Сообщить модератору
 Re: Как ускорить вычисление рангов ?  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
iap
SerVal
iap, спасибо, но что-то я никак не догадаюсь, как при помощи этих RANK() OVER() обновить ранги. :(
WITH CTE AS (SELECT [rank], r=DENSE_RANK() OVER(ORDER BY [total_credit] DESC) FROM [Users])
UPDATE CTE SET [rank] = r;
Бросается в глаза отсутствие WHERE.
Надо проапдейтить всю-всю таблицу [Users], да?!
Вообще-то, это большой грех!
Хотя бы так, что ли:
WITH CTE AS (SELECT [rank], r=DENSE_RANK() OVER(ORDER BY [total_credit] DESC) FROM [Users])
UPDATE CTE SET [rank] = r WHERE [rank] IS NULL OR [rank] <> r;
12 авг 12, 22:30    [13001420]     Ответить | Цитировать Сообщить модератору
 Re: Как ускорить вычисление рангов ?  [new]
SerVal
Member

Откуда: Москва, Ясенево
Сообщений: 139
iap
Бросается в глаза отсутствие WHERE.
Надо проапдейтить всю-всю таблицу [Users], да?!
Вообще-то, это большой грех!

Ну да, всю таблицу юзеров. А почему грех ?
*****
where не нужно. Добавиться может один user, а пересчитывать при этом надо всех.

Сейчас попробовал: 2636292 row(s) affected за 4 секунды !
Спасибо ! Класс !!!
*****
Правда, что такое CTE я так и не догадался. Сейчас проверю - правильно-ли всё пересчиталось. :)
Отпишусь здесь.
12 авг 12, 22:41    [13001442]     Ответить | Цитировать Сообщить модератору
 Re: Как ускорить вычисление рангов ?  [new]
SerVal
Member

Откуда: Москва, Ясенево
Сообщений: 139
Странно... Ежели в SQL Studio запускаю, всё замечательно.

WITH CTE AS (SELECT [project_rank], r=DENSE_RANK() OVER(ORDER BY [total_credit] DESC) FROM [Users])
UPDATE CTE SET [project_rank] = r;

А в Stored Proc вставляться не хочет. Ругается:

Msg 319, Level 15, State 1, Procedure UpdateUserRanks, Line 13
Incorrect syntax near the keyword 'with'.
If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause,
the previous statement must be terminated with a semicolon.
:(
12 авг 12, 23:04    [13001491]     Ответить | Цитировать Сообщить модератору
 Re: Как ускорить вычисление рангов ?  [new]
SerVal
Member

Откуда: Москва, Ясенево
Сообщений: 139
О ! Поставил точку с запятой перед этим стэйтментом, вставилось и в Stored Proc. :) Ура !
12 авг 12, 23:07    [13001500]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить