2011-12-29 4 views
2

Мне нужен кто-то, кто может сказать мне, что мне не хватает.Скалярная функция занимает так много времени

У меня есть эта скалярная функция в SQL Server 2008:

ALTER function [dbo].[SKU](@id1 int, @id2 int) 
returns int 
begin 
return (
SELECT SUM(Value) 
FROM Table 
where id_1 = @id1 
and id_2 = @id2) 
end 

И таблица выглядит так:

id_1  id_2 Value 
1004  1  10 
1004  1  30 
1004  2  100 
1005  1  90 
1005  1  5 
1005  1  5 

Если я выполняю:

select [dbo].[SKU](1004,1) 

возвращает 40 - Это нормально

select [dbo].[SKU](1004,2) 

возвращает 100 - OK

select [dbo].[SKU](1005,1) 

возвращает 100 - OK

На данный момент все кажется нормально, но моя таблица имеет почти Millon строки ... результат СК идет в ту же таблицу (обновить часть).

Но я побежал в течение двух часов в настоящее время, и до сих пор работает ...

Мой вопрос: Я никогда не видел таких, как долгое время потребляющего запроса. Все нормально? Я что-то упустил?

Спасибо !, и с новым годом! D:

+0

Как он используется при обновлении? У вас есть индекс покрытия на 'id_1, id_2', включая' Value'? –

+0

Можете ли вы опубликовать свой оператор обновления, интересно, создалось ли условие взаимоблокировки ... – Sparky

+0

таблица результатов обновления = dbo.SKU (id_1, id_2) – Jaxedin

ответ

1

Если изменение дизайна таблицы или программирования на нее не является вариантом, простым решением было бы создать индекс покрытия для полей, которые вы используете в своей функции.

Что-то вроде

CREATE INDEX IX_TABLE_ID_1_ID_2_VALUE ON dbo.Table (id_1, id_2) INCLUDE (Value) 
+0

Если завтра я нахожусь в новостях, то на вас загорится сервер, вы меня не знаете! ;) – Jaxedin

+0

@HarzIce - lol, я мог бы ручаться за вас. Люди поняли бы, прочитав это. –

1

Это не следует рассматривать как ответ, но попытка пробурить к реальной проблеме В настоящее время, это о том, как я interpretate действия, которые получают исполненные

Начиная с исходной таблицы

id_1  id_2 Value Result 
1004  1  10 NULL 
1004  1  30 NULL 
1004  2  100 NULL 
1005  1  90 NULL 
1005  1  5  NULL 
1005  1  5  NULL 

После update table set result = dbo.SKU(1004, 2) это станет

id_1  id_2 Value Result 
1004  1  10 40 
1004  1  30 40 
1004  2  100 40 
1005  1  90 40 
1005  1  5  40 
1005  1  5  40 

После того, как update table set result = dbo.SKU(1004, 1) это станет

id_1  id_2 Value Result 
1004  1  10 100 
1004  1  30 100 
1004  2  100 100 
1005  1  90 100 
1005  1  5  100 
1005  1  5  100 

После того, как update table set result = dbo.SKU(1005, 1) это станет (остаются)

id_1  id_2 Value Result 
1004  1  10 100 
1004  1  30 100 
1004  2  100 100 
1005  1  90 100 
1005  1  5  100 
1005  1  5  100 

и как-то после этого, результат делится на ID_2

id_1  id_2 Value Result 
1004  1  10 100 
1004  1  30 100 
1004  2  100 50 
1005  1  90 100 
1005  1  5  100 
1005  1  5  100 

Понятно, что моя интерпретация и то, что действительно, не совпадают (по крайней мере, я так надеюсь).

1

Это могли бы получить то, что вам нужно немного быстрее, если вы не должны использовать функцию.

;with sumVal 
as 
(
select t1.id_1, t1.id_2, SUM(t1.value) [result] 
from [table] t1 
group by t1.id_1, t1.id_2 
) 

select t2.*, s.result 
from sumVal s 
left join [table] t2 on s.id_1 = t2.id_1 and s.id_2 = t2.id_2 

Он провел менее чем за 5 секунд на более чем 800 000 строк на моем тесте.

+0

Спасибо за ответ! – Jaxedin

Смежные вопросы