Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL][PHP]Prośba o pomoc w optymalizacji skryptu - import CSV do MySQL
northwest
post 25.07.2013, 22:51:38
Post #1





Grupa: Zarejestrowani
Postów: 788
Pomógł: 1
Dołączył: 17.09.2004

Ostrzeżenie: (10%)
X----


Witam serdecznie,
Chciałbym prosić o pomoc w optymalizacji poniższego skryptu:
  1. $filename = "baza_ksiazek.csv";
  2. $handle = fopen("$filename", "r");
  3. $ilosc = 0;
  4. while (($data = fgetcsv($handle, 2000, ",")) !== FALSE) {
  5. $result = mysql_query("SELECT * FROM cms_produkty WHERE isbn = '$data[1]';", $connection);
  6. $ilosc_wierszy = mysql_num_rows($result);
  7. if ($ilosc_wierszy == 0) {
  8. if ($data['1'] != "") {
  9. $nazwakategorii = null;
  10. $nazwapodkategorii = null;
  11. $idkategorii = null;
  12. $idpodkategorii = null;
  13. $nazwakategorii = $data['12'];
  14. $nazwapodkategorii = $data['13'];
  15.  
  16. if ($nazwakategorii != "") {
  17. $result2 = mysql_query("SELECT * FROM cms_kategorie WHERE nazwa = '$nazwakategorii';");
  18. if (mysql_num_rows($result2) == 0) {
  19. mysql_query("INSERT INTO cms_kategorie (nazwa, enable) VALUES ('$nazwakategorii', '1');");
  20. $wynik = mysql_query("SELECT bf_id FROM cms_kategorie WHERE nazwa = '$nazwakategorii' ORDER by bf_id DESC LIMIT 1;;");
  21. while ($wartt2 = mysql_fetch_array($wynik)) {
  22. $idkategorii = $wartt2['bf_id'];
  23. }
  24. } else {
  25. $wynik = mysql_query("SELECT bf_id FROM cms_kategorie WHERE nazwa = '$nazwakategorii' ORDER by bf_id DESC LIMIT 1;;");
  26. while ($wartt2 = mysql_fetch_array($wynik)) {
  27. $idkategorii = $wartt2['bf_id'];
  28. }
  29. }
  30. }
  31.  
  32. //echo $idkategorii."<br/><br/>";
  33.  
  34. if ($nazwapodkategorii != "") {
  35. $result3 = mysql_query("SELECT * FROM cms_podkategorie WHERE nazwa = '$nazwapodkategorii';");
  36. if (mysql_num_rows($result3) == 0) {
  37. mysql_query("INSERT INTO cms_podkategorie (nazwa, enable, kategoria) VALUES ('$nazwapodkategorii', '1', '$idkategorii');");
  38. //echo "INSERT INTO cms_podkategorie (nazwa, enable, kategoria) VALUES ('$nazwapodkategorii', '1', '$idkategorii');";
  39. $wynik = mysql_query("SELECT bf_id FROM cms_podkategorie WHERE nazwa = '$nazwapodkategorii' ORDER by bf_id DESC LIMIT 1;;");
  40. while ($wartt2 = mysql_fetch_array($wynik)) {
  41. $idpodkategorii = $wartt2['bf_id'];
  42. }
  43. } else {
  44. $wynik = mysql_query("SELECT bf_id FROM cms_podkategorie WHERE nazwa = '$nazwapodkategorii' ORDER by bf_id DESC LIMIT 1;;");
  45. while ($wartt2 = mysql_fetch_array($wynik)) {
  46. $idpodkategorii = $wartt2['bf_id'];
  47. }
  48. }
  49. }
  50. $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[11]', '$data[4]', '$data[5]', '$data[6]', '$data[8]', '$data[7]', '$data[9]', '$data[10]', '$idkategorii', '$idpodkategorii', '1', '1');";
  51. //echo $save."<br/><br/>";
  52. $save = iconv('ISO-8859-2', 'UTF-8', $save);
  53. mysql_query("$save");
  54. //$ilosc = $ilosc + 1;
  55. if ($ilosc == 100) {
  56. die();
  57. }
  58. }
  59. }
  60. }


Skrypt ma działać w następujący sposób:
1. sprawdzić czy dany rekord już istnieje w bazie
2. sprawdzić czy kategoria jest już w bazie - jeśli nie, to dopisać
3. sprawdzić czy podkategoria jest już w bazie - jeśli nie, to dopisać
4. jeśli produktu nie ma w bazie - to go dopisujemy....

Skrypt działa... Ale prawdopodobnie da się go bardzo zoptymalizować pod względem wydajności.... smile.gif
Czy mógłbym prosić o pomoc?
Go to the top of the page
+Quote Post
freemp3
post 26.07.2013, 07:32:17
Post #2





Grupa: Zarejestrowani
Postów: 467
Pomógł: 77
Dołączył: 6.09.2008
Skąd: Miechów / Kraków

Ostrzeżenie: (0%)
-----


Oczywiście, że się da. Niepotrzebnie jest tylko select-ów. Zamiast odpytywać ciąglę bazę danych czy istnieje dany produkt, czy też kategoria możesz zrobić tablice, w której będziesz trzymał potrzebne informacje.
Przykładowo tworzysz tablice:
  1. $produkt = array();

w której bedziesz trzymał numery ISBN i zamiast sprawdzać czy produkt istnieje w bazie możesz sprawdzać przy pomocy funkci in_array. Jeśli nie ma to dodajesz, nowy produkt i na końcu dopisujesz nowy numer do tablicy.
W przypadku kategorii sytuacja będzie trochę inna bo potrzebne jest jej id, ale to też nie jest duży problem. Tworzysz tablice:
  1. $kategorie = array();

gdzie kluczem będzie jej nazwa, a wartością jej identyfikator z bazy danych. Przy sprawdzaniu wystarczy użyć funkcji array_key_exists. Jeśli klucz istnieje pobierasz numer id, jeśli nie dodajesz nową kategorie do bazy oraz do tablicy. Odnośnie pobierania numeru id nowo dodanej kategorii to służy do tego funkcja mysql_insert_id. Ten sam mechanizm tyczy się podkategorii.


--------------------
Niemożliwym jest stworzenie czegokolwiek idiotoodpornego, ponieważ idioci są wyjątkowo pomysłowi.

https://www.aroch.pl
https://themeforest.net/user/aroch
https://www.astroblog.aroch.pl
https://www.4geeks.pl
Go to the top of the page
+Quote Post
northwest
post 26.07.2013, 12:26:34
Post #3





Grupa: Zarejestrowani
Postów: 788
Pomógł: 1
Dołączył: 17.09.2004

Ostrzeżenie: (10%)
X----


mógłbym prosić o przykład jak to zrobić? smile.gif
Go to the top of the page
+Quote Post
freemp3
post 26.07.2013, 14:54:43
Post #4





Grupa: Zarejestrowani
Postów: 467
Pomógł: 77
Dołączył: 6.09.2008
Skąd: Miechów / Kraków

Ostrzeżenie: (0%)
-----


Przykład dla produku:
  1. $produkty = array();
  2. while (($data = fgetcsv($handle, 2000, ",")) !== FALSE) {
  3. if(!in_array($data[1], $produkty)){
  4. // kod dodający produkt
  5. mysql_query("$save");
  6. $produkty[] = $data[1];
  7. }
  8. }


Dla kategorii i podkategorii:
  1. $kategorie = array(); // zmienna musi być utworzona przed główną pętlą, w tym samy miejscu co zmienna $produkty
  2.  
  3. if(array_key_exists($nazwakategorii, $kategorie)){
  4. $idkategorii = $kategorie[$nazwakategorii ];
  5. }
  6. else{
  7. mysql_query("INSERT INTO cms_kategorie (nazwa, enable) VALUES ('$nazwakategorii', '1');");
  8. $idkategorii = mysql_insert_id();
  9. $kategorie[$nazwakategorii] = $idkategorii;
  10. }


Podobnie należy zrobić dla podkategorii, tzn stworzyć odpowiednią zmienną, w której będą przechowywane identyfikatory i dodać kod w odpowiednim miejscu.

Ten post edytował freemp3 26.07.2013, 14:57:50


--------------------
Niemożliwym jest stworzenie czegokolwiek idiotoodpornego, ponieważ idioci są wyjątkowo pomysłowi.

https://www.aroch.pl
https://themeforest.net/user/aroch
https://www.astroblog.aroch.pl
https://www.4geeks.pl
Go to the top of the page
+Quote Post
northwest
post 26.07.2013, 15:43:13
Post #5





Grupa: Zarejestrowani
Postów: 788
Pomógł: 1
Dołączył: 17.09.2004

Ostrzeżenie: (10%)
X----


tylko powyższy kod nie weryfikuje, czy w poszczególnych tabelach w bazie danych są już te rekordy...
Go to the top of the page
+Quote Post
freemp3
post 26.07.2013, 20:45:44
Post #6





Grupa: Zarejestrowani
Postów: 467
Pomógł: 77
Dołączył: 6.09.2008
Skąd: Miechów / Kraków

Ostrzeżenie: (0%)
-----


Zakładałem, że dane są importowane do pustej bazy. Jeśli masz coś już w bazie to możesz zrobić sprawdzanie najpierw w tablicach tak jak opisałem powyżej, jeśli w nich nie będzie to sprawdzasz w bazie. Jeśli dany produkt czy kategoria jest w bazie dodajesz do tablicy i następnym razem nie będzie konieczności sprawdzania w bazie.


--------------------
Niemożliwym jest stworzenie czegokolwiek idiotoodpornego, ponieważ idioci są wyjątkowo pomysłowi.

https://www.aroch.pl
https://themeforest.net/user/aroch
https://www.astroblog.aroch.pl
https://www.4geeks.pl
Go to the top of the page
+Quote Post
-north-
post 26.07.2013, 21:08:20
Post #7





Goście







import właśnie niestety do pełnej bazy sad.gif
Go to the top of the page
+Quote Post
freemp3
post 26.07.2013, 21:30:04
Post #8





Grupa: Zarejestrowani
Postów: 467
Pomógł: 77
Dołączył: 6.09.2008
Skąd: Miechów / Kraków

Ostrzeżenie: (0%)
-----


W takim razie zostaje sprawdzanie tak jak napisałem powyżej. Najpierw sprawdzaj tablice, a później dopiero w bazie danych.
Jeszcze ten warunek możesz poprawić:
Kod
if ($data['1'] != "")

Skoro wartość jest pusta i całe dodawanie jest pomijane to poniższy kod jest bezcelowy:
Kod
$result = mysql_query("SELECT * FROM cms_produkty WHERE isbn = '$data[1]';", $connection);
$ilosc_wierszy = mysql_num_rows($result);

Powinien się on znaleźć już po tym warunki kiedy wiadomo, że jest sens sprawdzania czy produkt już istnieje, a nie przed nim. Zyskujesz w tedy trochę cennego czasu na każde przejście pętli i przy dużych importach jest to widoczne.


--------------------
Niemożliwym jest stworzenie czegokolwiek idiotoodpornego, ponieważ idioci są wyjątkowo pomysłowi.

https://www.aroch.pl
https://themeforest.net/user/aroch
https://www.astroblog.aroch.pl
https://www.4geeks.pl
Go to the top of the page
+Quote Post
redeemer
post 27.07.2013, 14:04:22
Post #9





Grupa: Zarejestrowani
Postów: 915
Pomógł: 210
Dołączył: 8.09.2009
Skąd: Tomaszów Lubelski/Wrocław

Ostrzeżenie: (0%)
-----


Nic nie trzeba sprawdzać. Od tego jest indeks UNIQUE w bazie danych (+ ON DUPLICATE KEY ... w insertach).


--------------------
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 10.07.2025 - 11:10