insert 1 mln rekordów i zwis QA po 20000
Dariusz Tomon - 10-09-2006 00:16
insert 1 mln rekordów i zwis QA po 20000
Witam
Jest sobie procedurka (ponizej) insertujaca ok 1mln rekordów z tabeli plaskiej do róznych tabel wedle struktury (zródlo i tabele docelowe w tej samej bazie). Z niewidomych powodów procedura dziala w miare ok przez 20 min i po dodaniu ok 20000 rekordów spada jej wydajnosc do 1 rek / sek potem juz zamiera - nastepuje przy okazjin zwis QA z którego jest odpalana proc. Jak zabije z taskmanagera QA i odplae procedure jeszcze raz - doda znowu np. 30000 rek i dead. Ponizej procedura. Nie mam pojecia gdzie szukac bledu. Sprzet: serwer 4 procesorowy, miejsce na dysku jest.
ALTER procedure XX_IMPORT as
--##### SEKCJA DEKLARACJI
declare @nazwa nvarchar(255) declare @id int declare @id_woj int declare @id_miasto int declare @ulica nvarchar(255) declare @telefon nvarchar(255)
declare @id_branza int declare @www nvarchar(255) declare @mail nvarchar(255)
--nowo dodane declare @kod nvarchar(255) declare @numer_pos nvarchar(255) declare @kierunkowy nvarchar(255) declare @tb_firma_identity int declare @tb_adres_identity int --koniec
declare @id_firma int declare @id_adres int
set @nazwa = '' set @id = 0 set @id_woj = 0 set @id_miasto=0 set @ulica='' set @telefon='' set @kierunkowy='' set @id_branza=0 set @www='' set @mail=''
--nowo dodane set @kod = '' set @numer_pos ='' set @kierunkowy ='' --koniec
-- ####### KONIEC SEKCJI DEKLARACJI
--######## POCZATEK
begin
declare tb cursor for (select nazwa,id,id_woj,id_miasto,ulica,telefon,id_branza, www,mail,kod,numer_pos,kierunkowy from xx_zrodlo where id_portal is null)
open tb fetch next from tb into @nazwa,@id,@id_woj,@id_miasto,@ulica,@telefon,@id_ branza,@www,@mail,@kod,@numer_pos,@kierunkowy while @@fetch_status = 0 begin
IF @id_miasto <>0 AND @id_miasto is not NULL AND @id_woj<>0 AND @id_woj is not NULL AND @id_branza<>0 AND @id_branza is not NULL BEGIN
INSERT INTO TB_FIRMA (nazwa_firma,import) VALUES (@nazwa,@id) select @@Identity set @tb_firma_identity = @@Identity --select @id_firma = max(idTB_FIRMA) FROM TB_FIRMA UPDATE XX_ZRODLO set id_portal = 1 where id=@id INSERT INTO TB_FIRMA_BRANZA (idTB_FIRMA, idTB_BRANZA, HIERARCHIA,import) VALUES (@tb_firma_identity,@id_branza,30000,1) INSERT INTO TB_ADRES (ulica,nr_adresowy,kod,idTB_MIEJSOWOSC) VALUES (@ulica,@numer_pos,@kod,@id_miasto) select @@Identity set @tb_adres_identity = @@Identity --select @id_adres = max(idTB_ADRES) from TB_ADRES INSERT INTO TB_ADRES_FIRMA (idTB_FIRMA,idTB_ADRES,import) VALUES (@tb_firma_identity,@tb_adres_identity,1)
--przypadek telefonu komórkowego --IF substring(@telefon,1,1) = 0 IF @kierunkowy = 0 BEGIN INSERT INTO TB_KONTAKT (WARTOSC, idTB_NAZWA_KONTAKT, idTB_ADRES,import) VALUES (@telefon,5,@tb_adres_identity,1) END
--przypadek telefonu stacjonarnego --IF substring(@telefon,1,1) != 0 IF @kierunkowy <>0 AND @kierunkowy is not null BEGIN INSERT INTO TB_KONTAKT (WARTOSC, idTB_NAZWA_KONTAKT, idTB_ADRES,import) VALUES (@telefon,2,@tb_adres_identity,1) END
--przypadek adresu www
IF len(@www) > 1 BEGIN INSERT INTO TB_KONTAKT (WARTOSC, idTB_NAZWA_KONTAKT, idTB_ADRES,import) VALUES (@www,3,@tb_adres_identity,1) END
--przypadek adresu email
IF len(@mail) > 1 BEGIN INSERT INTO TB_KONTAKT (WARTOSC, idTB_NAZWA_KONTAKT, idTB_ADRES,import) VALUES (@mail,4,@tb_adres_identity,1) END
END
fetch next from tb into @nazwa,@id,@id_woj,@id_miasto,@ulica,@telefon,@id_ branza,@www,@mail,@kod,@numer_pos,@kierunkowy
END end
close tb deallocate tb
Jacek - 10-09-2006 00:16
Użytkownik "Dariusz Tomon" <d.tomon@mazars.pl> napisał w wiadomości news:eder7v$c8d$1@inews.gazeta.pl... > Witam > > Jest sobie procedurka (ponizej) insertujaca ok 1mln rekordów z tabeli > plaskiej do róznych tabel wedle struktury (zródlo i tabele docelowe w tej > samej bazie). > Z niewidomych powodów procedura dziala w miare ok przez 20 min i po > dodaniu ok 20000 rekordów spada jej wydajnosc do 1 rek / sek potem juz > zamiera - nastepuje przy okazjin zwis QA z którego jest odpalana proc. > Jak zabije z taskmanagera QA i odplae procedure jeszcze raz - doda znowu > np. 30000 rek i dead. > Ponizej procedura. > Nie mam pojecia gdzie szukac bledu. > Sprzet: serwer 4 procesorowy, miejsce na dysku jest.
Odpalic z Joba probowales?
Marcin A. Guzowski - 10-09-2006 00:16
> Jest sobie procedurka (ponizej) insertujaca ok 1mln rekordów z tabeli > plaskiej do róznych tabel wedle struktury (zródlo i tabele docelowe w tej > samej bazie). > Z niewidomych powodów procedura dziala w miare ok przez 20 min i po dodaniu > ok 20000 rekordów spada jej wydajnosc do 1 rek / sek potem juz zamiera -
Matko... 20tyś. rekordów insertujesz w 20 min.??
> nastepuje przy okazjin zwis QA z którego jest odpalana proc.
QA sam w sobie nic nie przetwarza - tylko wizualizuje zachowanie bazy. W stan zwisu wchodzi proces, w którym odpalono procedurę.
> Jak zabije z taskmanagera QA i odplae procedure jeszcze raz - doda znowu np. > 30000 rek i dead. > Ponizej procedura. > Nie mam pojecia gdzie szukac bledu.
> Sprzet: serwer 4 procesorowy, miejsce na dysku jest.
Jeżeli już podajesz takie parametry - to ważniejsza od liczby procesorów jest ilość RAMu, którą potrafi zaadresować dana wersja SQLServera.
> ALTER procedure XX_IMPORT (..)
Nie ma się co dziwić. Wystarczy jedno słowo: kursor - i wszystko jasne. Wykorzystujesz bazę danych, której twórcy w istotny sposób odeszli od przetwarzania jednorekordowego na rzecz operacji na zbiorach rekordów. Wyłącznie pod takie podejście jest zoptymalizowany silnik SQLServera. Sam T-SQL to język deklaratywny i nie można w nim kodować w ten sam sposób, co np. w C - na siłę budując pętle, deklarując wszędzie zmienne itd. Przez takie zachowanie, z szybkością pstryknięcia palca wysyłasz query optimezera na bezproduktywny urlop... Kursor stworzono dla bardzo wąskiej grupy zastosowań, a procedura, której kod przedstawiłeś - wcale takiego zastosowania nie wymaga.
Nawet, jeżeli procedura wykonywałaby się do końca w tym tempie co przez pierwsze 20 min, to i tak trzeba jej działanie uznać za żałosne.
Ale do rzeczy: zadaniem procedury jest pobranie danych z jednej tabeli i umieszczenie ich w kilku tabelach w lekko zmienionej postaci. Zapewniam Cię, że w Twojej procedurze nie ma niczego czego nie dałoby się zrobić kilkoma zapytaniami - po jednym na każdą tabelę docelową. Całą logikę możesz zawrzeć w warunku WHERE i konstrukcjach CASE... W zależności od potrzeb, możesz dowolnie sterować transakcjami - albo objąć transakcją całe ciało procedury, albo potwierdzać transakcję po każdym insercie, albo nawet podzielić insert na mniejsze grupy - jeżeli nie chcesz, aby log transakcyjny za bardzo puchł.
Wszystko nagle zacznie Ci działać kilkadziesiąt razy szybciej. Jeżeli nie będziesz wiedział jak się zabrać do przebudowy procedury, to skontaktuj się ze mną na priv.
-- Pozdrawiam, Marcin Guzowski http://guzowski.info
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
[ms sql] =?ISO-8859-2?Q?wy=B6wietlenie_pierwszych_5_rekord?==?ISO-8859-2?Q?=F3w_z_zapytania_=3F_odpowiednik_ROWNUM_w_o?== ?ISO-8859-2?Q?raclu_dla_MS_SQL=27a?=
[MySQL] =?ISO-8859-2?Q?Wy=B6wietlenie_kolejnej_pozycji=2C_?==?ISO-8859-2?Q?jak=B1_mia=B3by_dany_rekord=2C_gdybym_czyta=B3 _?==?ISO-8859-2?Q?wg_konkretnych_kryteri=F3w=2E_Da_si=EA_=3F?=
Jak =?ISO-8859-2?Q?zamieni=E6_dwa_pola_jednej_kolumny_?==?ISO-8859-2?Q?w_dw=F3ch_rekordach_za_pomoc=B1_jednego_zapyt? ==?ISO-8859-2?Q?ania=3F?=
[mysql/php] jak =?ISO-8859-2?Q?zliczy=E6_ilo=B6=E6_unikalnyc?==?ISO-8859-2?Q?h_rekord=F3w_w_jednym_zapytaniu=3F?=
=?ISO-8859-2?Q?WY=B6wietlenie_rekord=F3w_pocz=B1wszy_od_?==?I SO-8859-2?Q?danej_litery=2E=2E=2E?=
=?iso-8859-2?Q?=5BMySQL=5D_Wy=B6wietlenie_wszystkich_rekordow _zawierajacy?==?iso-8859-2?Q?ch_duplikat_a__moze_inna_struktura_bazy_danych ?=
[pgsql] Akcja w =?iso-8859-2?b?emFsZb9ub7ZjaQ==?= od liczby zmienionych =?iso-8859-1?q?rekord=F3w?=
[postgresql] kilka =?ISO-8859-2?Q?rekord=F3w_subquery_jako_?==?ISO-8859-2?Q?string?=
[mysql] Wyszukanie =?ISO-8859-2?Q?rekord=F3w=28powiazane_tabel?==?ISO-8859-2?Q?e=29?=
[MySQL]: Dodanie zliczania =?ISO-8859-2?Q?rekord=F3w_do_rozb?==?ISO-8859-2?Q?udowanego_zapytania?=
zanotowane.pldoc.pisz.plpdf.pisz.plred-hacjenda.opx.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|