Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Relacja wiele do wielu, wyszukiwanie w kilku tabelach jednym zapytaniem
mowgli91
post 6.05.2011, 17:22:47
Post #1





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 27.12.2008
Skąd: Szamotuły, Poznań

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


Witam serdecznie.

Tworząc panel zamówień z książkami natknąłem się na spory problem z wydajnością.

Dla zawężenia sprawy, przyjmijmy, że mam 3 tabele: ksiazki, autorzy, linkksiazkaautor. Pierwsza zawiera listę książek, druga listę autorów, trzecia powiązania między książką i autorem. Czyli jak widać, zachodzi relacja wiele do wielu (jedna książka może mieć kilku autorów, jeden autor może napisać kilka książek).

Z pobieraniem listy książek nie mam żadnego problemu: do listy książek doczepiam za pomocą podzapytania pole, które zawiera autorów danej książki wymienionych po przecinku (podzapytanie SELECT GROUP_CONCAT()).

Schody zaczynają się, jeżeli chcę wyszukać książki po autorach (wpisuje słowa kluczowe, rozdzielam je, każde z osobna przelatuje po bazie i pobieram wyniki gdzie wszystkie słowa zawierają się w danym autorze). Obecnie rozwiązanie ułożyłem, ale jest dość niewydajne:

  1. SELECT `ka`.`ksiazkaId` AS `id` FROM `linkksiazkaautor` AS `ka` RIGHT JOIN `autorzy` AS `a` ON a.id = ka.autorId WHERE (a.nazwa LIKE '%slowoKluczowe%')


Powyższe zapytanie pobiera listę zawierającą ID książek, które są powiązane z autorami pasującymi do danego słowa kluczowego. Z pobranej listy jest tworzony ciąg warunków dla kolejnego zapytania (do tabeli książek), w którym uwzględnione są również inne kryteria wyszukiwania (po wydawnictwie, po ISBN itp.).

A co w przypadku jeżeli prawie każdy autor ma w sobie literę "a" i użytkownik zażąda takiego wyszukania? Stworzony zostanie ciąg kilkudziesięciu tysięcy warunków, i takie zapytanie z miejsca zawiesza bazę danych i serwer.

Nie mogę wykonać żadnego JOIN'a do powyższego zapytania, bo inne kryteria wyszukiwania muszą się odnosić do pełnej listy książek, a nie tylko tej pasującej do autorów.

Mogę włączyć ograniczenie do minimum 4 znaków w słowach kluczowych i wtedy to jakoś znośnie chodzi, ale wiadomo że to jest kombinowanie dookoła...

Spotkał się ktoś z forumowiczów z podanym problemem? Byłbym wdzięczny za jakiekolwiek sugestie.

Pozdrawiam,
Kasper Warguła.



//Dodano po kilku godzinach:


Widzę, że nikt nie ma pomysłu. Ja poszedłem trochę do przodu i użyłem JOINów i GROUP_CONCAT (jednak się da):

  1. SELECT
  2. GROUP_CONCAT( a.nazwa SEPARATOR ', ') AS autorzy,
  3. k.id,
  4. k.tytul,
  5. k.stanDostepny,
  6. k.cenaSprzedazyDetal,
  7. k.vatSprzedaz,
  8. k.opis,
  9. k.isbn,
  10. k.liczbaStron,
  11. k.rokWydania,
  12. FROM
  13. ksiazki AS k
  14. LEFT JOIN
  15. linkksiazkaautor AS ka ON k.id = ka.ksiazkaId
  16. LEFT JOIN
  17. autorzy AS a ON a.id = ka.autorId
  18. GROUP BY k.id


Zapytanie jest OK. Tylko, że wykonuje się ogromnie długo. po dodaniu klauzuli WHERE k.id < 30 zapytanie trwa 3.4 sekundy, i rośnie w miarę rozrzeszania zakresu w warunku. Dodanie klauzuli LIMIT, nawet 1 nic nie zmienia.

Nie wiem jak Wy, ale ja już nie mam zielonego pojęcia, jak to rozwiązać...

Ten post edytował mowgli91 6.05.2011, 17:25:20


--------------------
Zapraszam na www.redtube.com
Go to the top of the page
+Quote Post
everth
post 6.05.2011, 17:53:17
Post #2





Grupa: Zarejestrowani
Postów: 782
Pomógł: 153
Dołączył: 21.07.2010

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


A może byłbyś taki dobry i załączył deklaracje tabel?


--------------------
Już mi się ani wiedzieć, ani tym bardziej myśleć nie chce.
[Think different]!
Go to the top of the page
+Quote Post
pmir13
post 6.05.2011, 20:20:00
Post #3





Grupa: Zarejestrowani
Postów: 282
Pomógł: 89
Dołączył: 12.04.2011

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


Wątek założyłeś w związku z wolnym wyszukiwaniem po zadanej frazie, teraz przedstawiasz zapytanie które tworzy listę książek z autorami, bez żadnej wyszukiwanej frazy, o co w ogóle pytasz? Zapytanie jest wolne, bo najpierw wszystko wrzucasz do wspólnego worka, dostając wielką połączoną tabelę na której później robisz grupowanie, zgaduję tylko że w explainie type jest ALL, rows idzie w kosmos, a w extra siedzi Using filesort, choćbyś nie wiem jak kombinował z indeksami.
Go to the top of the page
+Quote Post
mowgli91
post 6.05.2011, 21:55:20
Post #4





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 27.12.2008
Skąd: Szamotuły, Poznań

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


Wyszukiwanie frazy w drugim przypadku to tylko dołączenie WHERE, chodzi o sam mechanizm wyszukwiania który działa tragicznie wolno.
Deklaracja tabel została w skrócie podana, 3 tabele i opisane połączenia. Nie chodzi mi o wyszukiwanie konkretnych pól tylko na ogólnym problemie.

Wychodzi na to, że do optymalnego wyszukiwania użyję Lucyny w Zendzie.


--------------------
Zapraszam na www.redtube.com
Go to the top of the page
+Quote Post
everth
post 6.05.2011, 22:19:11
Post #5





Grupa: Zarejestrowani
Postów: 782
Pomógł: 153
Dołączył: 21.07.2010

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


Myślę że odpowiedź na twoje pytanie to 42. Nie pytaj skąd wiem.


--------------------
Już mi się ani wiedzieć, ani tym bardziej myśleć nie chce.
[Think different]!
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: 12.06.2025 - 18:00