Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: wyszukiwarka, kilka tabel
Forum PHP.pl > Forum > Bazy danych > PostgreSQL
czachor
Witam,
tworzę wyszukiwarkę i mam pewien problem.
Mam 6 tabel...

Kod
* articles
article_id //i kilka innych pól, ale wystarczy w tej chwili to jedno

* articles_lang
article_id | title | intro | txt

* news
news_id //jw.

* news_lang
news_id | title | intro | txt

* press_review
review_id //jw.

* press_review_lang
review_id | title | intro | txt


Daną frazę (w tym wypadku wyszukuję wszystkich wystąpień litery 'a' - %a%) mam znaleźć w 3 tabelach: articles_lang, news_lang, press_review_lang i jednocześnie wyciągnąć z tabel articles, news, press_review dodatkowe informacje (klucz obcy *_id).

Kombinuję z tym wszystkim i nie bardzo mi wychodzi. Doszedłem do wyszukiwania w 2 tabelach:
  1. SELECT a.article_id AS art_id, al.title AS art_title, al.intro AS art_intro, al.txt AS art_txt, NULL, NULL, NULL, NULL
  2. FROM articles_lang al
  3. INNER JOIN articles a USING (article_id)
  4. WHERE LOWER(al.title) LIKE LOWER('%a%') OR LOWER(al.intro) LIKE LOWER('%a%') OR LOWER(al.txt) LIKE LOWER('%a%')
  5.  
  6. UNION ALL
  7.  
  8. SELECT NULL, NULL, NULL, NULL, n.news_id AS news_id, nl.title AS n_title, nl.intro AS n_intro, nl.txt AS n_txt
  9. FROM news_lang nl
  10. INNER JOIN news n USING (news_id)
  11. WHERE LOWER(nl.title) LIKE LOWER('%a%') OR LOWER(nl.intro) LIKE LOWER('%a%') OR LOWER(nl.txt) LIKE LOWER('%a%')


To jest koszmar optymalizacyjny (nieoptymalna konstrukcja LIKE, czas wykonania zapytania: 12s!), dodatkowo nie wiem, jak do tego dołączyć 5 i 6 tabelę (press_review i press_review_lang). Kolejny "UNION" wywala błąd (skrót, nie wszystkie pola):
  1. SELECT a.article_id AS art_id, al.title AS art_t, NULL, NULL, NULL, NULL
  2. FROM articles_lang al
  3. INNER JOIN articles a USING (article_id)
  4. WHERE LOWER(al.title) LIKE LOWER('%a%') OR LOWER(al.intro) LIKE LOWER('%a%') OR LOWER(al.txt) LIKE LOWER('%a%')
  5.  
  6. UNION ALL
  7.  
  8. SELECT NULL, NULL, n.news_id AS news_id, nl.title AS news_title, NULL, NULL
  9. FROM news_lang nl
  10. INNER JOIN news n USING (news_id)
  11. WHERE LOWER(nl.title) LIKE LOWER('%a%') OR LOWER(nl.intro) LIKE LOWER('%a%') OR LOWER(nl.txt) LIKE LOWER('%a%')
  12.  
  13. UNION ALL
  14.  
  15. SELECT NULL, NULL, NULL, NULL, p.review_id, pl.title
  16. FROM press_review_lang pl
  17. INNER JOIN press_review p USING (review_id)
  18. WHERE LOWER(pl.title) LIKE LOWER('%a%') OR LOWER(pl.intro) LIKE LOWER('%a%') OR LOWER(pl.txt) LIKE LOWER('%a%')


Kod
ERROR:  UNION types text and integer cannot be matched


Byłbym wdzięczny za sugestie, jak optymalnie przeszukać pola title, intro, txt w każdej z 3 tabel i przy okazji wybrać dane z tabel im odpowiadających. Wydawało mi się to proste, ale albo coś mieszam i niepotrzebnie komplikuję, albo jest to bardziej zamieszane. Nie wiem, rozdrobnić to na więcej zapytań?

Niestety nie mam dostępu do serwera, więc tsearch i podobne rzeczy niestety odpadają sad.gif

Z góry dzięki za wszelką pomoc!
MikroUser
Optymalizacja niestety nie jest taka prosta sprawa.

Na Twoim miejscu:
  • Nie budowałbym dużego zapytania na cały ekran, tylko zbudowałbym wyszukiwanie po jednym zestawie tabel, potem po następnym itd.. Czyli po articles i articles_lang, potem po news i news_lang itd.
  • Jaki jest sens używania LOWER('%a%')? Zauważ, że za każdym porównaniem wykorzystujesz LOWER. Po prostu przekaż do zapytania wyszukiwany string w takiej postaci w jakiej potrzebujesz. Nie będzie się wtedy setki razy wykonywała się niepotrzebnie funkcja LOWER.
  • Spróbuj pozakładać indeksy na odpowiednie pola w tabelach.

Wiem, że to dużo nie wnosi, bo największym kłopotem jest LIKE, ale zawsze jakaś sugestia.

Pozdrawiam,
MikroUser
czachor
Jasne, dzięki. Racja z tym LOWER, o tym nie pomyślałem. Póki co mam właśnie wyszukiwanie po jednym zestawie, ale cały czas szukam (już chyba z ciekawości i na przyszłość), czy jest inny sposób na to.
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.