Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Optymalizacja wyszukiwania z INNER JOIN
Forum PHP.pl > Forum > Bazy danych > MySQL
Homiczek
Mam następujący problem.

Łącze 2 tabele:

1. zawiera główne dane itp i ma ID
2. zawiera powiązania pierwszej tabeli z trzecią tabelą: pola : ID, opcja_ID

Trzecia tabela zawiera nazwy opcji, ale do wyszukiwania potrzebuje znajdować takie które mają te opcje zapisane i nie potrzebuje ich nazw wtedy wyświetlać.

I problem polega na tym że potrzebuje wyszukiwać rekordy z tabeli 1 spełniające pewne tam kryteria, a dodatkowo spełniające opcje z powiązanej tabeli

mam zapytanko :
  1. SELECT mmdm.ID
  2. FROM mmdm.pierwsza AS mmdm
  3. INNER JOIN druga AS wt ON mmdm.ID = wt.opcja_ID
  4. WHERE wt.opcja_ID = '50' OR wt.opcja_ID = '35' OR wt.opcja_ID = '34'
  5. GROUP BY mmdm.ID
  6. HAVING count( * ) =3


to przykładowe zapytanie wyciąga wiersze z 1 tabeli które mają co najmniej zaznaczone opcje 50,34 i 35.
Wiem że to zapytanie jest pokręcone ale do takiego doszłem.

zapytanko działa, tylko dla 30000 rekordów w 1 tabeli i z miliona w drugiej to wykonuje sie 4 sekundy, a to trooche za dużo.

Jakby ktoś miał jakiś pomysł jak to wyszukiwanie przyśpieszyć to byłbym bardzo wdzięczny smile.gif

z góry thx
mwojcik
Jak na pytanie , w ktorym :
- laczysz 2 tabele
- grupujesz dane
- agregujesz dane
- masz warunki na dane
i ktore przerabia milion rekordow 4 sekundy to nie jest duzo.
Nie popadajmy w skrajnosci - baza nie wykonuje prostego selecta, w zwiazku z czym nie mozna oczekiwac, ze przy takiej ilosci danych wykona zapytanie w ok. sekunde.
osiris
4 sekundy to jednak troche za duzo jak na takie zapytanie.

hmm, skoro pobierasz tylko ID rekordow z pierwszej tabeli to po co wogole uzywasz inner joina, skoro pole ID masz tez w tabeli laczacej?
nie prosciej tak:
  1. SELECT id
  2. FROM tabela_laczaca WHERE opcja_id IN (50, 35, 34)
  3. GROUP BY id
  4. HAVING count(id) = 3

a jesli chcesz pobrac jakies pola z pierwszej tabeli to sprobuj:
  1. SELECT pole1, pole2, ...
  2. FROM pierwsza WHERE ID IN (
  3. SELECT id
  4. FROM tabela_laczaca WHERE opcja_id IN (50, 35, 34)
  5. GROUP BY id
  6. HAVING count(id) = 3
  7. )

Dlaczego w klauzuli WHERE wt.opcja_ID = '50' OR wt.opcja_ID = '35' OR wt.opcja_ID = '34' zapisujesz wartosci pol opcja_id jako tekst a nie jako liczby? Mysql musi potem wykonac niepotrzebna kowersje.

Jesli to nic nie pomoze to wklej tu wynik zapytania Twojego zapytania na poczatku dodajac fraze "EXPLAIN EXTENDED". Sporo informacji o optymalizacji zapytan znajduje sie MySQL Reference Manual http://dev.mysql.com/doc/refman/5.0/en/

Jesli masz zainstalowanego phpMyAdmin to przejrzyj dokladnie strone: Informacje o działaniu serwera.
Homiczek
Cytat
Dlaczego w klauzuli WHERE wt.opcja_ID = '50' OR wt.opcja_ID = '35' OR wt.opcja_ID = '34' zapisujesz wartosci pol opcja_id jako tekst a nie jako liczby? Mysql musi potem wykonac niepotrzebna kowersje.


no dzienki. Wcześniej nie zwracałem na to uwagi, a jakieś ułamki ms można urwać smile.gif

a pobieram pare danych z pierwszej tabeli oprócz id.


Przeglądam i sprawdzam optymalizacje smile.gif

Próbuje różnych dróg poprzez join i select - podselect; ewentualnie wchodzi w grę zapisywanie opcji po przecinku w głównej tabeli w jednej kolumnie. Bo nie chciałbym aby w miare wzrostu rekordów w tabelach wszystko zaczęło strasznie zwalniać :/
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.