[MSSQL] Czy można przyspieszyć taki update

0

Cześć, mam następujący update:

update fi SET
	fi.firstIn = dbo.getNextFirstIn(ids.BadID, ids.ComparedID)
from firstIns fi
left join @ids ids on fi.ID = ids.BadID
where fi.ID in (select badID from @ids)

Zapytanie ma zmienić tylko te wpisy w tabeli firstIns, których id znajdują się w tabeli @ids.
Dodatkowo nowe wartości muszą być odpowiednie - zwraca mi to funkcja getNextFirstIn(to po prostu 2 selecty)

Teraz tak: @ids to zmienna tabelaryczna. Założyłem na niej klucz główny:

declare @ids table(BadID bigint primary key, pole2 bigint, pole3 tinyint)

Jednak ten klucz przyspieszył wykonanie zaledwie o jakieś 5%

W tabeli firstIns będzie ok 4000 rekordów. W tabeli @ids ok 50 rekordów(Tylko 50).
Takie zapytanie wykonuje się ok 14 sekund. Funkcja getNextFirstIn to po prostu 2 selecty.

Ktoś ma jakiś pomysł, jak by to można było zrobić inaczej? Szybciej?

0

Bardzo możliwe, że selekty zawarte w funkcji getNextFirstIn wykonują się dla każdego update'owanego rekordu.

Spróbuj zrezygnować z funkcji getNextFirstIn a tabele z dwóch selectów w niej zawartych dodać do sekcji WHERE tak aby skontruować jedno złożone zapytanie UPDATE.

0

No, zszedłem do 4 sekund. Muszę jeszcze sprawdzić jakoś, czy dostaję faktycznie te dane, które powinienem dostać. Natomiast możliwe, że uda mi się jeszcze bardziej, bo już wiem chyba o co się oprzeć. No zobaczymy jak to będzie, dzięki!

0

Zrób sobie takie zapytanie:

select * 
from firstIns fi
left join @ids ids on fi.ID = ids.BadID

Następnie przeanalizuj wynik i pozbądz się tego: "where fi.ID in (select badID from @ids)", bo jest zupełnie zbędne a tylko wydłuża niepotrzebnie czas zapytania.

Podpowiedz chodzi o nulle w pewnych kolumnach.

0

I tu Cię zaskoczę.
Najpierw było bez Where, ale wtedy zmieniało mi z jakiegoś powodu wszystkie rekordy :|

0

Nie mówie że bez where (wtedy faktycznie nie ma żadnego ograniczenia i zmienione zostaną wszystkie rekordy), ale np tak:

where ids.BadID is not null
tak czy siak chcesz zrobić update tylko na tych rekordach których identyfikator występuje w innej tablicy. Przy left join gdy w drugiej tablicy takiego identyfikatora nie ma rekord i tak jest podawany do wyniku tylko zamiast oczekiwanych wartosci sa wstawiane nulle. Dlatego proponowałem żebyś się przyjrzał wynikowi selecta.

Można też zamiast left join użyć po prostu join. Wtedy zmienione zostaną tylko te rekordy których identyfikatory występują w drugiej tablicy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1