SQLite (sok adat minel gyorsabb importalasa)

Hello!

Van egy szoveg fajlom, ami tele van INSERT-ekkel. kb. 1,5 millio van beloluk. Az egesz fajl merete 300 MB koruli. Az lenne a kerdesem, hogy hogyan lehetne ezt minel gyorsabban vegrehajtatni SQLitetal. Vagy esetleg vmi izmosabb DBMS-el kene inkabb probalkoznom? Egyebkent azert valasztottam a SQLite-ot, mert sok szempontbol egyszerubb megoldasnak tunt (minimalis admin terhek, egyszeruen horodozhato - fogom a db fajlt, aztan viszem, ahova kell es nem utolso sorban konnyen kezelhetonek tunik shell scriptekbol is). Vannak esetleg valamilyen trukkos beallitasok, parameterek, amik sokat dobhatnak az egesz feldolgozas sebessegen? Elore is koszi az epito eszreveteleket es kritikakat is.

csg

Hozzászólások

Milyen gépen szeretnéd ezt a betöltést megtenni? A "fogom a db file-t" annyira nem egyszerű azért, gondolj bele picit. :) Egy alkalommal vagy rendszeresene kell ezt a 1,5m rekordot betölteni? Ha egy alkalom, akkor egy bármilyen gépen (lehetőleg az éleshez hasonló szoftverekkel) betöltöd egy fileba, majd felmásolod az élesre, service leállít, új file bemásol, service indít.

Mivel az SQLite serverless, ezért nem értem az utolsó mondatod utolsó hat szavát. Egyébként egy alkalomról lenne szó (pontosabban az is elképzelhető még, hogy többször egy alkalommal :-)). A "fogom a DB filet" pedig nekem egyszerűnek tűnik. Egy kisebb adatbázissal már megcsináltam, nagyobbal is meg fogom tudni - ha ráfér a pendrive-ra; ha nem akkor meg kiírom CD-re. Vagy előbb ráeresztek egy bzip2 -9 -et stb. A gép, most jelenleg úgy néz ki, hogy P4 (2.4 GHz) és 1GB RAM (és Windows XP - ez utóbbi lehet, hogy hátrány) Még esetleg a vinyó paraméterei lehetnének érdekesek, de azokról fogalmam sincs.

Rengeteget tud gyorsítani a műveleten ha az insert-álásokhoz egy ramdrive-ra átmásolod az adatbázis file-t. 300 MB-os méretnél talán még ez kivitelezhető.

Hm, ez jó ötletnek tűnik. Közben ebben a csoportban microsoft.public.windowsxp.setup_deployment egy ilyen véleményre bukkantam:

"(...) The main reason is that Windows already uses all unused RAM as a disk cache, so you already get RAM-disk-like access without doing anything."

Annyira megörültek neki, hogy kitették a webre is: http://www.michna.com/kb/wxramdisk.htm

Most akkor mi van? Egyébként Linux-on is ez lenne a helyzet, vagy a fickó marhaságokat beszél?

Az OS-ekben szokott lenni ilyen Cache-elés, sőt az adatbázis kezelőkben is. Amikor én ezt a ramdrive-os technikát használtam, egy kisebb adatbázist kellett feltöltenem, és valamiért sehogy sem akarta kikapcsolni az autocommit-ot. Ekkor egyszerűbb volt az egészet ramban csinálnom, mint keresgélni, hogy miért nem hajlandó rendesen viselkedni. Tehát lehet, hogy normális esetben tényleg nem lenne nagy különbség.

Hát az autocommit kikapcsolását most én sem látom az SQLite CLI-ben (csak drivereknél láttam - pl. Perl DBI). Esetleg még a PRIMARY KEY-t lehet érdemes leszedni a tábláról. Persze ez esetben talán nem ártana egy utólagos ellenőrzést végezni a biztonság kedvéért.

Egyébként lehet ezek között sebességbeli különbség (SQLite CLI parancsok):

.read SQL_INSERTS.sql

versus

.separator ", "
.load CSV_ROWS.TXT TARGET_TABLE

Vagy elképzelhető, hogy egy külön alkalmazás jobban csinálná ezt?

Elárulom azért, hogy én nagy naivan megpróbáltam ám a ".read SQL_INSERTS.sql" verziót - mindenféle optimalizálás nélkül. A futási idő 47 óra lett (igaz, ebből volt olyan 5 és fél óra, amikor a vírusírtó scannelte a vinyót; ill. több mint nyolc óra amikor egyéb programok is futottak a gépen (pl. Visual Studio, Firefox etc.). Szóval nem tudom, hogy ezek mennyire tartottak be az SQLite-nak. Az biztos, hogy így elég szívás volt ez az import. (De legalább nem mondhatom, hogy Megint 48 óra :-), ill. nektek már nem kell ezt kipróbálni.) Az SQLite DB mérete 172 MB lett - az SQL fájl mérete 317 MB volt.

probald ki a postgrest, nagyon jo, windowsra se bonyolult felrakni
postgresql.conf -ban erdemes tuningolni egy kicsit, ha sokszor csinalsz ilyet (work_mem, shared_buffers ...) es csodat fogsz latni :)
nalunk hasonlo mennyisegu adat percek alatt beimportalodik, bar ez erosen adatbazis fuggo is (indexek, tablarelaciok mennyisegetol nagyon fugg az ido)

--
Gabriel Akos

Koszi a tippet. Valahogy az elt az emlekeimben, hogy az SQLite kicsi es gyors - de legalabbis remeltem, hogy nem nagyon lassu. Most talaltam is egy linket (http://www.sqlite.org/cvstrac/wiki?p=PerformanceConsiderations), amit nem olvastam el teljsen, csak a lap aljan levo tesztet (a konfig durvan a prociban es az oprendszerben ter el az enyemtol). Nekem 1482214 sor kerult be a tablamba (es hat nagy atlagban 30 soronkent volt egy UPDATE egy masik tablara is (amiben osszesen volt 247 sor). Na most az egesznek a "sebessege" nekem 8.76 sor/sec (ha szabad igy megfogalmazni). Ez kb. 4-szer rosszabb Charles Thayer eredmenyenel (akinek ez a rossz ertek - 34 insert/sec - 8 millio sor utan kovetkezett be. Szoval vagy ennyit szamit a gyengebb proci, vagy a Win ront ennyit a helyzeten, vagy mindketto. :-( Majd egyszer megnezem PostgeSQL-el is. Most egy idore elment a kedvem a kiserletezgetestol :-)

Probalj meg egy tranzakciot kezdeni a feltoltes elott, es zard be a tranzakciot ha vegzett. Ha nem igy csinalod, akkor auto commit modban lesz, ami lassitja. Kb 20-50 szer lesz igy gyorsabb. De szerintem az SQLite.org-on a FAQ-ban is irjak.

Udv: BP

Csak az archívum kedvéért: nekem Linuxon, kikapcsolat AutoCommit mellett most csinált meg 17000 insert-et 3,5 sec alatt. Szóval vagy nagyon sokat javítottak rajta az elmúlt hónapokban, vagy valamit elszúrtatok.

ha nem kell minden insert utan lejatszani az indexek frissiteset, sokkal gyorsabb az insert. Ezert volt gyorsabb tranzakcios modban.

En elfelejtenem az sqlite-t, ha parhuzamosan tobb program is hasznalja, de foleg akkor, ha egyszerre tobb program szeretne bele irni. Azt ugyanis nem tudja, iraskor sqlite-ban a legkisebb lockolasi egyseg az adatbazis... Az pedig kicsit sok.