Autor | Zpráva | ||
---|---|---|---|
Kall Ell Profil * |
#1 · Zasláno: 19. 2. 2010, 09:43:56
Dobrý den, mám dotaz. Potřebuji načíst soubor csv pomocí php do sql databaze. Problém je, že je ten soubor hodně velký. Na menší soubor mě script normálně funguje. Ale já potřebuji načíst soubor o velikosti 128MB s 930 tisíc řádků. Je to jednorázové načtení. Nastavil jsem na serveru délku scriptu na 90s, víc bych to nerad nastavoval. 200 tisíc řádků to zvládne pak vyhazuje error o překročení délky scriptu. Chtěl bych ten soubor načíst třeba na třikrát, ale nepřišel jsem na to, jak nastavit načítání ze souboru od určitého řádku. Poradíte?
|
||
Joker Profil |
#2 · Zasláno: 19. 2. 2010, 09:49:39
Kall Ell:
V CSV bývají data uložená po řádcích, takže by mělo jít ten soubor rozdělit třeba po 100 000 řádcích a mělo by to normálně fungovat. „Chtěl bych ten soubor načíst třeba na třikrát“ Poznámka: Pokud máte 930 000 řádků a jedním cyklem zvládnete zpracovat maximálně 200 000, tak ho natřikrát asi nezpracujete. |
||
Kall Ell Profil * |
#3 · Zasláno: 19. 2. 2010, 10:00:55
Jasný tak bych to nějak chtěl udělat, ale jak mám nastavit, aby mě soubor načítal od řádku 200000 dál? S tím mám problém. Když načtu prvních 200K tak mě funkce fTell($soubor) vyhodí, že je ukazacel na pozici 28469534. Pomocí funkce fSeek($soubor, '28469534') nastavím ukazatel na místo kde zkončil. Po dalším spuštění scriptu pokracuje od toho místa, ale funkce fTell($soubor) mě vrací stále stejnou hodnotu 28469534, takže se dál jak je 400K nedostanu. Existuje nějaká proměná, která by ukazatel nastavila na potřebný řádek? fseek posune ukazatel o daný počet znaků v souboru, což je pro mě nepoužitelný, protože každý řádek má jiný počet znaků.
|
||
nightfish Profil |
#4 · Zasláno: 19. 2. 2010, 10:08:24
Kall Ell:
„funkce fTell($soubor) mě vrací stále stejnou hodnotu 28469534“ to moc nedává smysl - mohlo by to být voláním funkce ftell na nesprávném místě druhou možností je rozsekat soubor na více souborů (v nějakém textovém editoru, který nemá problémy s velkými soubory) a každý zpracovávat samostatně |
||
Kall Ell Profil * |
#5 · Zasláno: 19. 2. 2010, 10:27:22
Ha, sakra, jsem idiot, to mě nenapadlo. To bude asi nejrychlejší. Nic méně by mě to stejně zajímalo, proč to dělá. Přikládám ten script asi to bude lepší. Zatím není hotový. Zatím jsem udělal jen script, který má za úkol projít celej soubor a zjistit, kolik mají jednotlivá pole maximálně znaků. Abych mohl vytvořit tabulku v DB. pozdeji nahradím počítání znaku, zápisem do db.
$pocet_radku = 0; echo ("nacteni dat z csv souboru do tabulky<p>"); $fp = fopen ("zdroje/cenik.csv","r"); while($data = fgetcsv ($fp, 10000, ";")) { $num = count($data); $kontrola = fSeek($fp, '1481'); $pocet_radku++; if ($data[0] == 'destinace') { // tohle je nacteni prvniho radku, kde je popis sloupcu // soubor obsahuje cenik exportovany z jine databaze for ($c=0; $c<$num; $c++) { $popis_sloupcu[$c] = $data[$c]; $pocet_znaku[$c] = '0'; } } else { if ($pocet_znaku[1] < strlen($data[1])) { $pocet_znaku[1] = strlen($data[1]);} for ($c=0; $c<$num; $c++) { if ($pocet_znaku[$c] < strlen($data[$c])) { $pocet_znaku[$c] = strlen($data[$c]); } } } if ($pocet_radku == 200000) { print "<br> pozice v souboru zustala na: ". fTell($fp) . "<br>"; break; } } foreach ($pocet_znaku as $klic => $hodnota){ print "sloupec: ". $popis_sloupcu[$klic] ." ma nejvice znaku: $hodnota<br>"; } print "<br>pocet radku je $pocet_radku<br>"; fclose ($fp); |
||
nightfish Profil |
#6 · Zasláno: 19. 2. 2010, 10:30:06
vidím správně, že se na řádku 6 při každém průchodu cyklem nastaví pozice v souboru na 1481. bajt?
|
||
Kall Ell Profil * |
#7 · Zasláno: 19. 2. 2010, 10:49:34
Jsem idiot, prošel jsem to tolikrat, že mě taková blbost unikla. Víc očí víc vidí. Dík za postřeh.
|
||
Nox Profil |
#8 · Zasláno: 19. 2. 2010, 11:17:09
Nebylo by lepší použít něco jako http://dev.mysql.com/doc/refman/5.1/en/load-data.html ? Nevim, ptám se, funkce vypadá určená přímo na toto (ikdyž možná může být problém s posláním tak velkýho souboru...)
|
||
TomášK Profil |
#9 · Zasláno: 19. 2. 2010, 11:41:05
LOAD DATA INFILE, na které odkazuje Nox, je podstatně rychlejší než hromadný INSERT - pokud si dobře pamatuju, tak asi 10x. Určitě bych ji použil, pokud je to možné.
|
||
Časová prodleva: 14 let
|
0