Скалярная функция занимает так много времени - PullRequest
2 голосов
/ 29 декабря 2011

Мне нужен кто-то, кто скажет мне, что мне не хватает.

У меня есть эта скалярная функция в 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 - ОК

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

возвращает 100 - ОК

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

Но я запускал его два часа и все еще работает ...

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

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

Ответы [ 3 ]

1 голос
/ 29 декабря 2011

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

Что-то вроде

CREATE INDEX IX_TABLE_ID_1_ID_2_VALUE ON dbo.Table (id_1, id_2) INCLUDE (Value)
1 голос
/ 30 декабря 2011

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

;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 строк.

1 голос
/ 29 декабря 2011

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

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

 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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...