Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Duży problem z dużą bazą
Forum PHP.pl > Forum > Bazy danych > MySQL
budda1989
Witam serdecznie, opis sytuacji:

posiadam tabelę z prezentacjami, oraz inną tabelę ze zdjęciami do prezentacji.
dużo prezentacji wygasło, a ich zdjęcia zaśmiecają mi tabelę zdjęć tworząc zestaw powyżej pół miliona rekordów.

Chciałbym odchudzić bazę, jednak mam duży problem. Napisałem sobie skrypt, który pobiera z tabeli prezentacje ID prezentacji których status to zero i usuwa row z tabeli zdjęcia. Jednak skrypt działa tak wolno, że musiałbym poczekać z miesiąc aż skonczy się to robić.

Zastanawiam się nad napisaniem jednego zapytania sql które:
1)z tabeli prezentacje pobiera id_prezentacje gdzie status = 0
2) z tabeli zdjecia usówa rekordy w których id_prezentacje = pobrane ID

podejmowałem próby z zapytaniami zagnieżdżonymi jednak nie udało mi się rozwiązać problemu.

przykład zapytania które testowałem:

  1. UPDATE `zdjecia` SET STATUS=0 WHERE `id_prezentacja` = (SELECT `id_prezentacja` FROM `prezentacja` WHERE STATUS=0)


zgłasza mi błąd

- Subquery returns more than 1 row

Nie wiem naprawdę jak to napisać, i co więcej, czy przy takiej ilosci rekordów ( prezentacje = 300 000, zdjecia = 500 000 ) da się to zrobić 1 zapytaniem

Uprzejmie proszę o pomoc

PS. urządza mnie jedno z dwóch rozwiązań, update zdjęcia z nieaktywnej prezentacji i oznaczenie jego status=0 LUB usunięcie zdjęć z nieaktywnych prezentacji smile.gif
bpskiba
nie ten operator

...WHERE `id_prezentacja` IN (SELECT...
rzymek01
zamiast IN lepiej używać EXISTS, bo IN przetrzymuje wszystkie dane odnośnie wybranych wierszy/kolumn,
a exists ustawia jedynie flagę true/false, co jest po pierwsze szybsze, a po drugie, przy dużych bazach, w ogóle daje kryterium wykonalności zapytania w rozsądnym czasie smile.gif
BaN
Wygląda na to, że zdjęcia są przyporządkowane do więcej niż jednej prezentacji, wiec może zdarzyć się sytuacja, że dane zdjęcie jest przyporządkowane do dwóch prezentacji, w jednej status=0, w drugiej - nie. Czy na pewno wtedy zdjęcie ma mieć status=0? Jeśli nie, to zapytanie z IN będzie raczej nieprawidłowe, z EXISTS też, raczej należałoby wtedy zastosować warunek NOT EXISTS:
  1. UPDATE zdjecia
  2. SET `status`=0
  3. WHERE NOT EXISTS (SELECT 1 FROM prezentacja WHERE prezentacja.id_prezentacja=zdjecia.id_prezentacja AND prezentacja.status<>0)


Kasowanie:
  1. DELETE FROM zdjecia
  2. WHERE NOT EXISTS (SELECT 1 FROM prezentacja WHERE prezentacja.id_prezentacja=zdjecia.id_prezentacja AND prezentacja.status<>0)


Jeżeli prezentacja.status przyjmuje tylko dwie wartości 0 i 1, to można pozmieniać te zapytania i zamiast prezentacja.status<>0 wpisać prezentacja.status=1

Co do czasu działania, to zapytania powinny działać przyzwoicie o ile na zdjecia.id_prezentacja założony jest indeks, zaś w tabeli prezentacja indeks na dwóch polach (id_prezentacja,status), ale jak jest tylko na id_prezentacja, to nie powinno to stanowić dużej różnicy
budda1989
Cytat(rzymek01 @ 28.07.2012, 23:02:21 ) *
zamiast IN lepiej używać EXISTS, bo IN przetrzymuje wszystkie dane odnośnie wybranych wierszy/kolumn,
a exists ustawia jedynie flagę true/false, co jest po pierwsze szybsze, a po drugie, przy dużych bazach, w ogóle daje kryterium wykonalności zapytania w rozsądnym czasie smile.gif



Dziękuję za zainteresowanie tematem oraz odpowiedź, jednak podane polecenie wywala mi wszystkie rekordy z tabeli zdjęcia. Coś na pewno robię źle

  1. SELECT `id_zdjecia` FROM `zdjecia` WHERE EXISTS (SELECT `id_prezentacja` FROM `prezentacja` WHERE `status`=0);


próbuję narazie selectem, aby zobaczyć czy robi się to co ma się robić, boję się w ciemno dawać update

BaN, dziękuję za odpowiedź
Jedno zdjęcie może być przypisane tylko do 1 prezentacji, natomiast jedna prezentacja może mieć nawet 50 zdjęć.

zastanawiam się jak powinien wyglądać select

  1. SELECT `id_prezentacja`
  2. FROM `prezentacja`
  3. WHERE NOT EXISTS (SELECT 1 FROM `prezentacja` WHERE `prezentacja`.`id_prezentacja`=`zdjecia`.`id_prezentacja` AND `prezentacja`.`status`=1)


Wywala mi błąd o nieistniejącej tabeli #1054 - Unknown column 'zdjecia.id_prezentacja' in 'where clause'

prezentacja.status przyjmuje tylko 2 wart 0 i 1

na zdjecia.id_prezentacja NIE jest założony indeks
w tabeli prezentacja indeks to id_prezentacja, w tabeli zdjecia indeks to id_zdjecia, ale w tabeli zdjecia znajduje sie tez pole id_prezentacja.


skopiowałem sobie tab ze zdjęciami i na niej teraz testuje, niestety wywala ten sa błąd przy delete
:/
BaN
Cytat(budda1989 @ 28.07.2012, 23:14:41 ) *
...
zastanawiam się jak powinien wyglądać select


z zapytania, które podałeś nie wiem co chcesz wyciągnąć, jeśli chcesz zobaczyć dane o zdjęciach, które są przyporządkowane do prezentacji, które mają status 0, to zmienia się tylko początek zapytania

  1. SELECT *
  2. FROM zdjecia
  3. WHERE NOT EXISTS (SELECT 1 FROM prezentacja WHERE prezentacja.id_prezentacja=zdjecia.id_prezentacja AND prezentacja.STATUS=1)


Cytat(budda1989 @ 28.07.2012, 23:14:41 ) *
...
na zdjecia.id_prezentacja NIE jest założony indeks


W zapytaniu uaktualniającym czy kasującym może to nie mieć znaczenia, bo i tak baza musi wszystkie zdjęcia sprawdzić, ale ten indeks jest raczej wymagany jeśli chcesz wyciągnąć wszystkie zdjęcia do danej prezentacji, bo są to pewnie zapytania typu:
  1. SELECT ...
  2. FROM zdjecia
  3. WHERE id_prezentacja=... /* być może jeszcze uwględniasz pole status? */


Zatem lepiej założyć indeks, bo przy takim zapytaniu baza musi sprawdzić wszystkie wiersze jeśli nie ma indeksu
budda1989
Witam ,dziękuję za odpowiedzi, niestety nadal cały czas "Unknown column 'zdjecia.id_prezentacja' in 'where clause'"
pomimo, iż na 100% nazwy wpisałem dobrze, próbowałem ręcznie + klikając na odpowiednią nazwę kolumny w phpmyadmin... :/
BaN
Jakie dokładnie zapytanie wykonujesz, że masz taki błąd? Jeżeli te które podałeś poprzednio:
  1. SELECT `id_prezentacja`
  2. FROM `prezentacja`
  3. WHERE NOT EXISTS (SELECT 1 FROM `prezentacja` WHERE `prezentacja`.`id_prezentacja`=`zdjecia`.`id_prezentacja` AND `prezentacja`.`status`=1)

to logiczne, że jest błąd, bo dwa razy podałeś tabelę prezentacja, tabela zdjecia nie jest uwzględniana, więc nie może być warunku z odwołaniem do pola tej tabeli, podałem przecież przykłady, które powinny działać
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.