Witam serdecznie.
To mój pierwszy post. Jestem Mariusz - nie jestem zawodowym programistą, programowanie to hobby jak dla mnie.
Stworzyłem pewien program, obsługujący SQLite, jest to baza danych, zawierająca jedynie dane kontaktowe oraz pewne dane liczbowe podane przez użytkownika a później po przeliczeniu generuje raport do pliku Excela. Działa rewelacyjnie, potrafi dla każdego pracownika zaoszczędzić wiele godzin liczenia. Jednak jest pewien problem. Z czasem baza się rozrosła, i nastąpił problem z czasem zapisu. Juz dla 500 pracowników, zapis na 1GB RAM, oraz na procesorze Core 2 Duo około 2Ghz trwa nawet 30-40 sekund. Na szybszych komputerach i tak zapisuje to kilkanaście sekund.
Co ciekawe odczyt jest natychmiastowy.
Oto kod który wykonuje się bardzo długo ( otwieranie, łącznie bazy ze ścieżka jest realizowane w procedurze OnCreate formularza głównego, tak samo zamykanie bazy w OnClose ):
procedure TForm2.zapisz_bazeClick(Sender: TObject);
var
i:integer;
begin
if czy_wczytano_poprawnie = true then
begin
SQL_Baza.ExecSQL('DROP TABLE pracownicy');
SQL_Baza.ExecSQL('CREATE TABLE pracownicy (imie TEXT,nazwisko TEXT,pesel TEXT ,tel TEXT,email TEXT, miejscowosc TEXT,kod TEXT,poczta TEXT,data_ur TEXT,miejsce_ur TEXT,imie_ojca TEXT,imie_matki TEXT,skarbowy TEXT,skarbowy_adres TEXT,notatki TEXT,czy_student BOOLEAN) ');
end;
for i := 0 to CheckListBox1.Items.Count-1 do
begin
pracownik[i].czy_student:= CheckListBox1.Checked[i] ;
SQL_Baza.ExecSQL('INSERT INTO pracownicy VALUES ("' + pracownik[i].imie +'", "' + pracownik[i].nazwisko +'","' + IntToStr(pracownik[i].pesel)+ '","' + pracownik[i].tel + '","'+ pracownik[i].email + '","' + pracownik[i].miejscowosc
+'","' + pracownik[i].kod+'","' + pracownik[i].poczta +'","' + pracownik[i].data_ur +'","' + pracownik[i].miejsce_ur
+'","' + pracownik[i].imie_ojca +'","' + pracownik[i].imie_matki +'","' + pracownik[i].skarbowy +'","' + pracownik[i].skarbowy_adres +'","' + pracownik[i].notatki
+'","' + BoolToStr(pracownik[i].czy_student) +'")');
wait(1,CheckListBox1.Items.Count,i); // jest to wyświetlanie paska postępu w nowym oknie na środku
end; // od for
Form5.Close;
end;
Co ciekawe odczyt jest błyskawiczny oto kod:
procedure TForm2.wczytaj_bazeClick(Sender: TObject);
var
i : integer;
begin
CheckListBox1.Clear;//wyczysc liste pracowników
SQL_Tabela := SQL_Baza.GetTable('SELECT * FROM pracownicy'); // pobieranie wszystkich wartosci z tabeli
// ShowMessage('liczba wpisów w bazie: ' + INttoStr(SQL_Tabela.RowCount ));
for i := 0 to SQL_Tabela.RowCount - 1 do
begin
pracownik[i].imie := SQL_Tabela.FieldByName['imie'] ;
pracownik[i].nazwisko := SQL_Tabela.FieldByName['nazwisko'] ;
pracownik[i].pesel := StrTOINt64(SQL_Tabela.FieldByName['pesel']);
pracownik[i].tel := SQL_Tabela.FieldByName['tel'] ;
pracownik[i].email := SQL_Tabela.FieldByName['email'] ;
pracownik[i].miejscowosc := SQL_Tabela.FieldByName['miejscowosc'] ;
pracownik[i].kod := SQL_Tabela.FieldByName['kod'] ;
pracownik[i].poczta:= SQL_Tabela.FieldByName['poczta'] ;
pracownik[i].data_ur:= SQL_Tabela.FieldByName['data_ur'];
pracownik[i].miejsce_ur:= SQL_Tabela.FieldByName['miejsce_ur'];
pracownik[i].imie_ojca:= SQL_Tabela.FieldByName['imie_ojca'] ;
pracownik[i].imie_matki:= SQL_Tabela.FieldByName['imie_matki'];
pracownik[i].skarbowy:= SQL_Tabela.FieldByName['skarbowy'] ;
pracownik[i].skarbowy_adres:= SQL_Tabela.FieldByName['skarbowy_adres'] ;
pracownik[i].notatki:= SQL_Tabela.FieldByName['notatki'] ;
pracownik[i].czy_student :=StrToBool( SQL_Tabela.FieldByName['czy_student']);
CheckListBox1.Items.Add(pracownik[i].nazwisko + ' ' + pracownik[i].imie) ;
CheckListBox1.Checked[i]:= pracownik[i].czy_student ;
SQL_Tabela.Next;
wait(1,SQL_Tabela.RowCount,i);
end;
Form5.Close;
SQL_Tabela.Free;
CheckListBox1.ItemIndex:= 0;
Label9.Caption:= 'Pracowników: '+ Inttostr(CheckListBox1.count);
CheckListBox1.OnClick(self);
Wrzucam wszystko do tablicy rekordów takiej:
type TPracownicy = record
imie : string[100];
nazwisko : string[100];
pesel : int64;
tel :string[20];
email : string[200];
miejscowosc :string[50];
kod :string[50];
poczta :string[50];
data_ur :string[50];
miejsce_ur :string[50];
imie_ojca :string[50];
imie_matki :string[50];
skarbowy :string[255];
skarbowy_adres :string[255];
notatki :string[255];
czy_student :Boolean;
end;
Niestety wymagane jest częste zamykanie bazy bo trzeba sie przełączać pomiędzy różnymi pracodawcami bo różni pracownicy pracują w różnych firmach, i dla każdego pracownika są tworzone oddzielne bazy godzin i ilości przepracowanych "produktów" które muszą być zliczane a raporty eksportowane do Excela.
Proszę o pomoc, dlaczego odczyt jest taki błyskawiczny a zapis taki powolny??? gdzie robię błąd?
Z góry dziękuję za pomoc. Pozdrawiam Mariusz