@PrzemysławWiśniewski:
Przetestowałem Array DML. Niestety tu w moim przypadku nie sprawdziło się. Czas wykonania niemal identyczny.
ArrayDML dla PostgreSQL działa od wersji 8.1, dla niższych wersji jest emulowane (czyli insert po insercie) i nie będzie tu żadnego wzrostu wydajności.
Poza tym, jak chcesz mieć mega szybko po stronie bzy danych to warto wyłączyć na czas ładowania danych indeksy, triggery i klucze obce. A włączyć je po załadowaniu danych.
Oczywiście jeśli można.
Chyba problem leży w tym, że muszę wiersz po wierszu wyciągać dane z pliku XML i dlatego to tyle trwa.
Nie do końca; trwa tu ładowanie tego XMLa do pamięci i budowanie DOM.
Jeśli zależy Ci na naprawdę wydajnym przetwarzaniu XMLa, to musisz popatrzeć w stronę SAX.
Osobiście od dawna korzystam z OXML:
http://www.kluug.net/oxml.php
Kliknij w zakładkę performance na w/w stronie i sam zobacz.
Gdy wyrzuciłem z kodu wszelkie operacje łączenia tekstu i wykonywania zapytania do bazy
Stop, stop; jak łączysz te teksty?
Zresztą nieważne jak, ale jak nie używasz TStringBulder
to zacznij go używać zamiast używać Pos
, Copy
, string + string
, itp.
Jak wykonywanie zapytań - jakich zapytań?
To nie jest po prostu insert into
tylko jakieś dodatkowe sprawdzenie danych w bazie przed zapisałem danych?
i została sama pętla przelatująca po wierszach (<row>) z pliku XML to czas trwania jest niemal identyczny jak z dodawaniem rekordów do bazy. Zaobserwowałem, że do 50 tys rekordów jeszcze w miare szybko leci a później zaczyna zwalniać po każdym kolejnym 1000.
Co może powodować takie zachowanie?
Transakcje bazodanowe.
Jak nimi zarządzasz?
Tak czy inaczej powinieneś robić to mniej więcej tak (dzielić na paczki, które będą objęte jedną transakcją):
- BeginTransaction;
- Dodawanie 1000 (tu trzeba potestować ile będzie najlepiej) wierszy.
- CommitTransaction;
I powtarzasz to dla wszystkich wierszy z XML...
var node, nodeRow: TXMLNode;
count, i: Integer;
p1, p2: string;
xml: TNativeXml;
begin
xml.LoadFromFile('file.xml');
node := xml.Root.FindNode('root');
count := node.ContainerCount - 1;
for i := 0 to count do
begin
nodeROW := node.Containers[i];
p1 := nodeRow.Containers[0].Value;
p2 := nodeRow.Containers[1].Value;
lbl1.Caption := IntToStr(i);
end;
end;
Takie proste coś (zmiana tekstu w labelku) potrafi porządnie zwolnić, jeżeli to robisz przy każdej iteracji.