2014-04-14 9 views
8

Używam Talend do ładowania danych do bazy danych serwera sql.jak ładować dane szybciej dzięki serwerowi talend i sql

Wygląda na to, że najsłabszym punktem mojej pracy nie jest przetwarzanie danych, ale efektywne obciążenie w mojej bazie danych, które nie jest szybsze niż 17 wierszy/sek.

Śmieszne jest to, że mogę uruchomić 5 zadań w tym samym czasie, a wszystkie będą ładowane z szybkością 17 rzutów/sek.

Co może wyjaśnić tę powolność i jak poprawić prędkość?

Dzięki

Nowe informacje:

Prędkość transferu między moim pulpicie a serwerem jest o 1MByte

Moja praca zobowiązuje każde 10 000

Używam serwera sql 2008 R2

An d schematu używam do moich zadań jest tak:

enter image description here

+2

Czy funkcja Talend ma funkcję "Bulk Load", "Bulk Insert" lub "Bulk Copy"? – RBarryYoung

+0

Sprawdź swój sprzęt. 17 jest żałosny nawet dla pojedynczego gwintowanego pojedynczego słowa SQL. Może twój serwer przypomina bardziej telefon komórkowy lub laptop. Jakie jest opóźnienie między aplikacją a serwerem? – TomTom

+0

Powolność może być spowodowana dowolnym czynnikiem, np. Szybkością sieci między talendem a twoją bazą danych, sposobem, w jaki zadanie jest pisane w talencie, talend ma komponenty ładowania zbiorczego dla serwera sql, ale z normalnymi komponentami serwera sql wydajność, której doświadczasz jest bardzo niska . Sugerowałbym wspomnieć o więcej szczegółów, takich jak to, co jest sql, które są uruchomione, czy jest jakiekolwiek przetwarzanie wykonywane na stronie talé, jakie talend składniki używasz w pracy itp. – garpitmzn

Odpowiedz

0

Znalazłem gdzie ten problem wydajność przyjść formularza.

Wykonuję INSERT OR UPDATE, jeśli zastąpię go prostym INSERT, prędkość wzrasta do 4000 wierszy/s.

Czy wydaje się, że jest to dopuszczalne tempo?

W każdym razie potrzebuję mojego INSERT OR UPDATE, więc chyba utknąłem.

+1

Nie jestem zaznajomiony z Talendem, ale możesz podzielić na dwa oddzielne INSERT/AKTUALIZUJ kroki/zadania? Jeden w całości robi inserty, a drugi tylko robi aktualizacje (dla rekordów, które wcześniej sprawdziłeś pod kątem aktualizacji). –

+0

Co powiesz na "Wstaw lub aktualizuj na duplikacie klucza lub unikatowym indeksie"? Spowoduje to wykonanie komendy MySQL INSERT ... ON DUPLICATE KEY INSERT. Niestety nie znalazłem sposobu (jeszcze), aby działało to w więcej niż jednym wierszu naraz, ale przynajmniej powinien on działać dużo szybciej niż "Wstaw lub Aktualizuj", ponieważ odczyt nie jest wymagany. – fool4jesus

13

Baza danych INSERT OR UPDATE metody są niewiarygodnie kosztowne, ponieważ baza danych nie może grupować wszystkich zatwierdzeń do zrobienia wszystkiego naraz i musi wykonywać je wiersz po wierszu (transakcje ACID wymuszają to, ponieważ jeśli próbują wykonać wstawkę, a następnie zawiodą, wszystkie inne zapisy w tym zatwierdzeniu również zawiedzie).

Zamiast tego w przypadku dużych operacji zbiorczych zawsze najlepiej jest ustalić, czy rekord zostanie wstawiony lub zaktualizowany przed przekazaniem zatwierdzenia do bazy danych, a następnie wysłaniem 2 transakcji do bazy danych.

Typowe zadanie, które wymagało tej funkcji, mogłoby zmontować dane, które mają być INSERT OR UPDATEd, a następnie przeszukać tabelę bazy danych dla istniejących kluczy podstawowych. Jeśli klucz podstawowy już istnieje, możesz wysłać go jako UPDATE, w przeciwnym razie jest to INSERT. Logika do tego może być łatwo wykonana w komponencie tMap.

Insert or Update Job Example

W tej pracy mamy pewne dane, które chcemy INSERT OR UPDATE do tabeli bazy danych, która zawiera pewne istniejące wcześniej dane:

Initially loaded data

I chcemy dodać następujące dane aby go:

Insert or Update data

Zadanie działa poprzez wrzucenie nowych danych do komponentu tHashOutput, dzięki czemu można go używać wielokrotnie w tym samym zadaniu (po prostu umieszcza je w pamięci lub w dużych instancjach można je buforować na dysk).

Po tej jednej partii danych odczytuje się komponent tHashInput i bezpośrednio do tMap. Innym tHashInput komponent jest wykorzystywany do uruchamiania parametryzowany zapytanie do stołu:

Parameterised Query Parameter Config

można znaleźć this guide to Talend and parameterised queries pożytecznego. Odtąd zwrócone rekordy (czyli tylko te wewnątrz bazy danych) są używane jako odnośniki do tMap.

ta jest konfigurowane jako INNER JOIN znaleźć zapisy, które muszą być UPDATED z odrzuceń z INNER JOIN być włożona:

tMap configuration

Wyjścia te następnie tylko przepływ oddzielić tMySQLOutput elementom UPDATE lub INSERT w razie potrzeby. I w końcu, gdy główne subjob jest kompletne, my commit zmian.

+0

Dzięki, zajrzę do niego i wrócę z moim rozwiązaniem (i rezultatem czasu). – Krowar

+0

Po prostu buduję szybką pracę, aby pokazać, jak można to zrobić. Przesyłaj zrzuty ekranu, aby Ci pomóc. – ydaetskcoR

+0

Ta praca wygląda ładnie, ale przy stole przejściowym możesz zrobić to samo, jak myślę. Sprawdź moją odpowiedź. –

0

Na podstawie Twojej notatki wkładki są o rząd wielkości szybsze niż aktualizacje (4000 vs 17/s) - Wygląda na to, że musisz spojrzeć na swoje indeksy DB. Dodanie indeksu zgodnego z parametrami aktualizacji może znacznie przyspieszyć aktualizacje. Oczywiście ten indeks może spowolnić nieco wstawianie.

Możesz także sprawdzić plan wykonania kwerendy dla swojego zapytania o aktualizację, aby sprawdzić, czy używa on jakichkolwiek indeksów. How do I obtain a Query Execution Plan?

+1

Prawdziwy problem, że nie można hurtować swoich UPSERTS. Musisz więc wstawić/zaktualizować 1 wiersz naraz. –

+1

Prawda. Jednak 17-sekundowa aktualizacja samej aktualizacji może być łatwo zwiększona o odpowiedni indeks bez zwiększania złożoności. – user1452132

0

Powinieneś wykonać stół pomostowy, w którym wstawiasz wiersze.

Na podstawie tej tabeli pomostowej wykonywane jest zapytanie DELETE z t * SQLrow.

DELETE FROM target_table 
WHERE target_table.id IN (SELECT id FROM staging_table); 

Tak więc wiersze, które chcesz zaktualizować, już nie istnieją.

INSERT INTO target_table 
SELECT * FROM staging_table; 

Spowoduje to przeniesienie wszystkich nowych/zmodyfikowanych wierszy.

+2

To niezły pomysł, ale w ten sposób tracisz transakcje ACID. Co się stanie, jeśli twoja praca z jakiegoś powodu spadnie po usunięciu wierszy? Aby to działało, MUSISZ zatwierdzić usunięcie przed wykonaniem wstawki, aby nie można było wycofać błędu w przypadku niepowodzenia pracy. Jeśli nie dbasz o to, to tak, to jest prostsze i myślę, że jest lepszy sposób, ale zawsze chciałbym transakcji ACID dla takich rzeczy. – ydaetskcoR

+0

Z oracle można użyć scalania: http://psoug.org/reference/merge.html –

3

Myślę, że odpowiedź @ydaetskcoR jest idealna na teorycznym punkcie widzenia (dzielenie wierszy, które wymagają wstawiania od tych do Aktualizacji) i daje działające rozwiązanie ETL przydatne dla małego zestawu danych (kilka tysięcy wierszy).

Wykonywanie wyszukiwania, aby móc zdecydować, czy wiersz musi zostać zaktualizowany, jest kosztowne w ETL, ponieważ wszystkie dane przechodzą tam iz powrotem między urządzeniem Talend a serwerem DB.

Po przejściu setek tysięcy lub nawet milionów rekordów musisz przejść z ETL do ELT: po prostu wczytujesz swoje dane do tabeli tymczasowej (zgodnie z propozycją z @Balazs Gunics), a następnie używasz SQL do manipulować nim.

W tym przypadku po wczytaniu danych (tylko WSTAW = szybka, jeszcze szybciej przy użyciu komponentów OBCIĄŻENIE BULKOWE) wyda się POŁĄCZENIE ZEWNĘTRZNE między tabelą tymczasową a tabelą docelową, aby podzielić wiersze, które już tam są (potrzeba aktualizacji) i inni.

To zapytanie daje wiersze musisz wstawić:

SELECT staging.* FROM staging 
LEFT OUTER JOIN destination ON (destination.PK = staging.PK) 
WHERE destination.PK IS NULL 

Ten drugi wiersze musisz aktualizować:

SELECT staging.* FROM staging 
LEFT OUTER JOIN destination ON (destination.PK = staging.PK) 
WHERE destination.PK IS NOT NULL 

To będzie rzędy wielkości szybciej niż ETL, ALE będziesz musiał użyć SQL do operowania na swoich danych, podczas gdy w ETL możesz używać Javy, ponieważ WSZYSTKIE dane są przesyłane do serwera Talend, więc często pierwszy krok na lokalnym komputerze jest wstępny do przetworzenia danych w java (aby wyczyścić i zweryfikować), a następnie uruchom go w DB, gdzie używasz łączyć, aby go załadować właściwą drogę.

Oto zrzuty ekranowe ELT JOB. INSERT or UPDATE ELT job

How to distinguish between rows to insert or update

0

miałem te same dane ładowanie problem w serwerze DB2. Również ustawiłem zatwierdzenie na 10000, ale gdy wybrałem opcję wsadową (na tym samym ekranie opcji komponentu) wydajność znacznie się poprawiła. Kiedy przeniosłem commit i wsad do 20000, zadanie trwało od 5 godzin do poniżej 2 minut.

Powiązane problemy