Konkurs książkowy – runda 6
Zaczniemy jak zwykle od podsumowania ostatniej rundy … niestety ale tym razem znowu nie udało się wyłonić zwycięzy. Michał w swoim poście o tempdb zaczął dobrze kombinować – problem z tempdb jest tylko taki że po restarcie serwera dane z niej znikną … natomiast z bazy master nie znikną;-) Tak wiem pytanie było “podchwytliwe” ale myślę że jest to naprawdę ciekawa własność SQL Server w wersji Express. No dobrze a teraz odpowiedź na pytanie: ograniczenie 4GB – jest ograniczeniem na sumaryczny rozmiar wszystkich plików danych w bazie danych. Na całym serwerze tylko baza master i baza tempdb nie mają tego ograniczenia (zgaduje że baza resource również ale jako że ona nie jest bezpośrednio dostępna dla użytkownika to nie wchodzi w grę). Poniżej screen z mojej testowej instancji SQL Server Express.
No a teraz czas na kolejne pytanie – tym razem będzie ono dotyczyło SSIS.
Pytanie #6
Często zdarza się że w trakcie przelewania danych pomiędzy różnymi systami musimy wykonać tzw. upsert (update lub insert), zadanie z tej rundy jest związane właśnie z tym procesem … proszę o zbudowanie pakietu który wykona upsert na tabelach. Kod “tworzący” poniżej:
USE tempdb
GO
CREATE TABLE dbo.zrodlo (
id INT,
VALUE VARCHAR(100))
GO
DECLARE @i INT
SET @i = 1
WHILE (@i < 100000)
BEGIN
INSERT INTO dbo.zrodlo
(id,VALUE)
VALUES (@i, Cast(Checksum(Newid()) AS VARCHAR))
SET @i = @i + 1
END
GO
SELECT id, Cast(Checksum(Newid()) AS VARCHAR) AS VALUE
INTO dbo.cel
FROM dbo.zrodlo t1
WHERE t1.id%2 = 1
Kod tworzy 2 tabele w bazie tempdb - cel zadania: pobrać dane z tabeli dbo.zrodlo i wykonać upsert na tabeli cel, tabele łączymy po identyfikatorze, updateowane pole to value. Książkę dostanie osoba, której SSIS będzie najszybszy. Test będzie przeprowadzany u mnie na laptopie – więc jeśli w pakiecie są używane zewnętrzne komponenty to będę musiał je móc u mnie uruchomić…
Na odpowiedzi czekam do poniedziałku 21 września, 20:00
Witam
Prosty jeden klocek “Execute SQL Task” z zawartościa:
“update dbo.cel
set [value]=z.[value]
from dbo.zrodlo (nolock) z
where z.[id]=cel.[id]
go
insert into dbo.cel ([id], [value])
SELECT dbo.zrodlo.[id], dbo.zrodlo.[value]
FROM dbo.zrodlo (nolock) LEFT JOIN
dbo.cel (nolock) ON dbo.cel.[id] = dbo.zrodlo.[id]
WHERE (dbo.cel.[id] IS NULL)
go”
Można prosić o sprawdzenie czasu ?
Pozdrawiam
GG
Być może nie wyraziłem się wystarczająco dokładnie – dane mają zostać POBRANE do pakietu. Dane MUSZĄ przepłynąć przez pakiet.
Tylko po co przepłacać?
Możesz podać czas wykonania, aby było porównanie?
Na podstawie tego czasu każdy będzie miał punkt odniesienia
w realizacji wersji “przepływających przez pakiet”.
Pozdrawiam
GG
Temat jaki rzuciłem jest tematem, z którym spotyka się każdy pracujący z SSIS – bardzo często są wykonywane upserty danych niekoniecznie pochodzących z tej samej bazy danych – często źródłem są pliki płaskie pobrane z ftp czy inne systemy z którymi nie można się inaczej podłączyć.
Podejść w samym SSIS można zastosować kilka – liczę na to zostanie przedstawione kilka rozwiązań a osoby je tworzące czegoś się nauczą (jeśli tego jeszcze nie umieją).
Tak więc jeszcze raz przypominam – celem tego zadania nie jest napisanie update’a odpalonego z mangement studio – dane są uproszczone do minimum tylko po to żeby nie było “a ja mam więcej danych”, “a moje dane są trudniejsze”. Celem zadania jest wykonanie upserta przy pomocy pakietu SSIS przez który przepłyną dane ;-)
Ponadto twoje zapytanie i tak nie jest optymalne, profiler pokazuje że można je napisać szybciej:
– CPU|READS|WRITES|DURATION
– 328,59792,152,329 — twoja wersja
– 297,59796,152,301 — moja wersja
Zapomniałeś podać tę poprawiona moją – Twoją wersję.
Niby 10%, ale 0,3 sek przy wersjach pakietowych będzie pomijalne.
pozdr
GG
Nie zapomniałem podac “mojej” czy “twojej” wersji po prostu inaczej napisałem inserta. Myślę że zmiana była tak mała że wiele osób samemu na nią wpadnie – nie zawsze chodzi o to żeby wszystko podawać na tacy. I żeby jasne było – zapytania puszczałem kilka razy i różnica za każdym razem była podobna.
Ponieważ cel nie zawiera wierszy o id nie występujących w zrodlo
więc:
truncate table dbo.cel
insert dbo.cel(id, VALUE)
SELECT t1.id, t1.VALUE
FROM dbo.zrodlo t1
:)