Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] Usuwanie zduplikowanych wpisow
Forum PHP.pl > Forum > Przedszkole
Agape
Mam w tabeli produkty z ich nazwami, do wgrywanych produktow robie dodatkowa kolumne `nazwa_unikalna` gdzie zapisuje tytul obciety do max 50 znakow. Nastepnie mam cos takiego w uproszczeniu:
  1. $produkty_unikalne = array();
  2. foreach ($produkty as $produkty_){
  3. if(in_array($produkty_['nazwa_unikalna'], $produkty_unikalne)){
  4. //jezeli produkt o takiej nazwie juz wystepowal, usuwaj powielony
  5. }else{
  6. //zbieraj unikalne do porownania
  7. $produkty_unikalne[] = $produkty_['nazwa_unikalna'];
  8. }
  9. }

czyli jezeli napotka drugi i kolejny produkt ktory ma taka sama nazwe unikalna, to usuwa go zeby nie bylo takich samych poduktow w bazie. Problem w tym ze baza ma pareset tysiecy rekordow i funkcja ta wykonuje sie pare minut, czym wiecej produktow przerobi tym bardziej zwalnia. Potrzebuje ja zastapic poleceniem sql, zeby zostawialo pierwszy produkt z taka nazwa a usuwalo nastepne, niestety nie mam pojecia jak to zrobic :/

7 minut dokladnie wykonuje sie to zapytanie, jakbym zszedl do 2 byloby idealnie ...
Agape
nie moge dac unique index na ta kolumne bo przestanie mi to dzialac tak jak potrzebuje i jak reszta rzeczy jest skonstrulowana, wlasnie chodzi o to ze musze to zrobic zapytaniem, tak baza jest skonstrulowana
trueblue
7 minut wykonuje się zapytanie czy ten kod?
Ten kod nie powinien tyle się wykonywać. Zresztą zapytanie (nie wiem jak wygląda) również nie.

Zainteresuj się wyzwalaczem before insert.
Agape
ten kod, baza ma 130 MB i zawiera 130 000 rekordow wiec pewnie dla tego, kazdy produkt sie pobiera pojedynczo i usuwa pojedynczo (jezeli jest zduplikowany) wiec to troche zapytan jest.
trueblue
No, to już jakieś rozwiązanie masz - usuwać jednym zapytaniem. Zebrać id i wykonać jeden delete.
Agape
Wlasnie nie chodzi o to ze dlugo sie usuwa, tylko dlugo mieli. Pobieram cala baze (ale tylko id, nazwe i nazwa_unikalna) jednym zapytaniem i czas ktory napisalem jest dla bazy w ktorej nie ma duplikatow, samo sprawdzanie calej bazy tyle zajmuje, mielenie tablicy, nie wiem czy in_array tak dlugo zajmuje czy co ... wiec w php jest jakis problem :/

mysle ze czym wiecej ma wartosci w tablicy, tym dluzej musi je porownywac i dla tego tym tym bardziej zwalnia z czasem wykonywania :/

zrobilem kolumne `id` auto increment i zapytanie:
  1. DELETE b1 FROM `baza` b1, `baza` b2 WHERE b1.nazwa_unikalna = b2.nazwa_unikalna AND b1.id > b2.id;

i po 11 min zabilem proces, w phpmyadmin nawet sie nie dalo wejsc :/
moze dodac index do tej kolumny ? moze cos innego niz in_array ? mecze sie z tym dlugi czas i nie moge dojsc jak to przyspieszyc :/

trueblue
$produkty_unikalne=array_unique(array_column($produkty,'nazwa_unikalna')));

viking
A to dlaczego nie kasujesz ich od razu na bazie tylko mielisz w PHP?
DELETE .... WHERE ... (SELECT...)
Agape
Panowie bardzo dziekuje wam za zainteresowanie tematem, znalazlem problem. Powyzszy skrypt wykonywal sie 7 min (ten na samej gorze). Zmienilem z in_array ktore jest bardzo wolne na isset ktore jest mega szybkie, ponizszy skrypt ktory robi to samo, a tylko jedna funkcja zostala zmieniona wykonuje sie w 1 sekunde !

  1. $produkty_unikalne = array();
  2. foreach ($produkty as $produkty_){
  3. if(isset($produkty_unikalne[$produkty_['nazwa_unikalna']])){
  4. //jezeli produkt o takiej nazwie juz wystepowal, usuwaj powielony
  5. }else{
  6. //zbieraj unikalne do porownania
  7. $produkty_unikalne[ $produkty_['nazwa_unikalna'] ] = 'x';
  8. }
  9. }


chodzi na pewno o to ze in_array przeszukuje cala tablice (ponad 100 tys rekordow) a isset probuje odczytac pojedyncza wartosc, jesli jest git, jesli nie to juz nie szuka w tysiacach rekordow tylko zwraca ze nie ma. Nie wiedzialem ze jest az taka roznica
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.