Out of memory przy imporcie danych z CSV do MySQL

0

Witam serdecznie,
Mam problem z zaimportowaniem 70MB pliku CSV do MySQL.
Mam następujący skrypt:

$filename = "baza_ksiazek.csv";
        $handle = fopen("$filename", "r");
        $ilosc = 0;
        while (($data = fgetcsv($handle, 2000, ",")) !== FALSE) {
            $result = mysql_query("SELECT bf_id FROM cms_produkty WHERE isbn = '" . mysql_real_escape_string($data[1]) . "' LIMIT 1;", $connection);
            $ilosc_wierszy = mysql_num_rows($result);
            if ($ilosc_wierszy == 0) {
                if ($data['1'] != "") {
                    $nazwakategorii = null;
                    $nazwapodkategorii = null;
                    $idkategorii = null;
                    $idpodkategorii = null;
                    $nazwakategorii = $data['12'];
                    $nazwapodkategorii = $data['13'];

                    if ($nazwakategorii != "") {
                        $result2 = mysql_query("SELECT * FROM cms_kategorie WHERE nazwa = '$nazwakategorii';");
                        if (mysql_num_rows($result2) == 0) {
                            mysql_query("INSERT INTO cms_kategorie (nazwa, enable) VALUES ('$nazwakategorii', '1');");
                            $wynik = mysql_query("SELECT bf_id FROM cms_kategorie WHERE nazwa = '$nazwakategorii' ORDER by bf_id DESC LIMIT 1;;");
                            while ($wartt2 = mysql_fetch_assoc($wynik)) {
                                $idkategorii = $wartt2['bf_id'];
                            }
                        } else {
                            $wynik = mysql_query("SELECT bf_id FROM cms_kategorie WHERE nazwa = '$nazwakategorii' ORDER by bf_id DESC LIMIT 1;;");
                            while ($wartt2 = mysql_fetch_assoc($wynik)) {
                                $idkategorii = $wartt2['bf_id'];
                            }
                        }
                    }

                    //echo $idkategorii."<br/><br/>";

                    if ($nazwapodkategorii != "") {
                        $result3 = mysql_query("SELECT bf_id FROM cms_podkategorie WHERE nazwa = '$nazwapodkategorii' LIMIT 1;");
                        if (mysql_num_rows($result3) == 0) {
                            mysql_query("INSERT INTO cms_podkategorie (nazwa, enable, kategoria) VALUES ('$nazwapodkategorii', '1', '$idkategorii');");
                            //echo "INSERT INTO cms_podkategorie (nazwa, enable, kategoria) VALUES ('$nazwapodkategorii', '1', '$idkategorii');";
                            $wynik = mysql_query("SELECT bf_id FROM cms_podkategorie WHERE nazwa = '$nazwapodkategorii' ORDER by bf_id DESC LIMIT 1;;");
                            while ($wartt2 = mysql_fetch_assoc($wynik)) {
                                $idpodkategorii = $wartt2['bf_id'];
                            }
                        } else {
                            $wynik = mysql_query("SELECT bf_id FROM cms_podkategorie WHERE nazwa = '$nazwapodkategorii' ORDER by bf_id DESC LIMIT 1;;");
                            while ($wartt2 = mysql_fetch_assoc($wynik)) {
                                $idpodkategorii = $wartt2['bf_id'];
                            }
                        }
                    }
                    $save = "INSERT INTO cms_produkty (nazwa, obrazek, isbn, cena, autor, wydawca, strony, opis, rok, podatek, cena2, kategoria, grupa, typrekordu, enable) VALUES ('$data[3]', '$data[15]', '$data[1]', '$data[9]', '$data[4]', '$data[5]', '$data[6]', '$data[8]', '$data[7]', '$data[10]', '$data[11]', '$idkategorii', '$idpodkategorii', '1', '1');";
                   
                    $save = iconv('ISO-8859-2', 'UTF-8', $save);
                    mysql_query("$save");
                   
                }
            }

Import ma sprawdzić czy dana kategoria/podkategoria/produkt istnieją w bazie - i jeśli nie - to go dodać...
Problem w tym, że skrypt zwraca błąd: Fatal error: Out of memory (allocated 43778048) (tried to allocate 42997761 bytes) in /ksiegarnia/import.php on line 55

Czy ktoś ma może pomysł jak wybrnąć z tego problemu?

Z góry dziękuję bardzo za pomoc,
Northwest

1

W pierwszej kolejności spróbuj na początku skryptu dodać linijkę:

ini_set("memory_limit","512M");

(pod warunkiem, że masz wystarczającą ilość ramu dostępną).
Przy tak małym pliku (70 MB) ten zabieg powinien wystarczyć.
Natomiast gdybyś kiedyś miał ładować pliki dużo większe (idące w GB), to zazwyczaj dobrym pomysłem jest rozbijanie ich na kilka części i generalna optymalizacja kodu.

Nie wczytywałem się w kod, ale jeśli wczytujesz z CSV to może Cię zainteresować zapytanie "LOAD DATA INFILE ... " w MySQLu, które samo zassie dane.

0

ten limit nie pomógł niestety :( ciągle ten sam błąd :(

0

Zoptymalizuj skrypt, żeby wszystko wczytywał z pliku jak najmniejszymi kawałkami - inaczej zapychasz pamięć.

0
 $result3 = mysql_query("SELECT bf_id FROM cms_podkategorie WHERE nazwa = '$nazwapodkategorii' LIMIT 1;");

To jest 55 linia....

A jak zrobić to "kawałkami"?

0

No dobra to jako zwykły post:

spróbuj z tym: http://php.net/manual/en/function.mysql-free-result.php

0

nie pomogło :(
mogę wrzucić na neta tegp csv....

0

pokaż kod po zmianie

0

PHP bawię się od niedawna i przyznam, że wiele w tym wątku nie rozumiem.
Analizowałem podany kod i to moje pytania i uwagi:

  1. po co jest zmienna $ilosc_wierszy?
  2. zmienne tworzone z $data - aż się prosi o użycie stałych jako indeksów tej macierzy zamiast zmiennych
  3. po co przypisywać zmiennej null i za chwilę jakąś wartość?
  4. różne sposoby nazewnictwa zmiennych
  5. po co wybierać wartość id (autoincrement) przez SELECT skoro jest chyba na to funkcja?
  6. po co pętla while dla powyższej operacji skoro w zapytaniu jest LIMIT 1?
  7. po co robić powyższe 2x w kodzie dla podkategorii?
  8. aż się prosi o załadowanie kategorii i podkategorii do array - o czym pisał kolega
  9. $idkategorii = null i linia niżej - potrzebne to?

A wracając do meritum, to czy mam rozumieć, że PHP nie zwalnia zasobów (bądź nie nadąża ze zwalnianiem) $resultx po tym jak są podstawiane do nich nowe wartości?

1 użytkowników online, w tym zalogowanych: 0, gości: 1