Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> LEFT JOIN z osobnymi warunkami dla każdej z tabel
lukesh
post
Post #1





Grupa: Zarejestrowani
Postów: 113
Pomógł: 14
Dołączył: 25.08.2006

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


Cześć! Mam dwie tabele: items i repetitions. W tabeli items przechowywane są różne pytania (fiszki). W momencie, gdy użytkownik odpowie na pytanie/wykona jakieś ćwiczenia, informacja o tym zapisywana jest w tabeli repetitions. Chcąc wyświetlić z tabeli items pytania, których użytkownik jeszcze nie odpowiedział (a więc nie mają odpowiadającego im rekordu w tabeli repetitions), wykonuję zagnieżdżone zapytanie z LEFT JOIN. Problem polega na tym, że zarówno w tabeli items i repetitions, poszczególny elementy należą do różnych grup. W tabeli items będzie docelowo około 30 tys. wierwszy, które podzielone będą na 3 grupy po 10 tys. każda. Tabela repetitions docelowo powinna zawierać do około 10 milionów rekordów.
Oryginalne zapytanie wygląda w ten sposób:
  1. SELECT * FROM (SELECT id, question, answer FROM items WHERE courseid='$courseid') AS items LEFT JOIN (SELECT itemid, nextrepetition FROM repetitions WHERE userid='$userid' AND courseid='$courseid') AS repetitions ON items.id=repetitions.itemid WHERE repetitions.nextrepetition IS NULL LIMIT 1

Jak widać w zapytaniu, najpierw wybieram fragment pierwszej tabeli, potem fragment drugiej tabeli i łączę je ze sobą tak, aby wybrane zostały wszystkie rekordy z tabeli po lewej stronie i odpowiadające im rekordy z tabeli po prawej stronie. Niektóre rekordy z tabeli po lewo nie mają swoich odpowiedników po prawo i to własnie te rekordy wybieram, używając WHERE IS NULL.
Czy ktoś mógłby doradzić mi, jak takie pytanie można najlepiej zoptymalizować? Myślałem np. o podzieleniu tabeli items na 3 tabele tak, aby nie było potrzeby określania warunku na tej tabeli. A może najlepszym rozwiązaniem będzie każdemu użytkownikowi z góry przepisać zakładane 10 tys. rekordów odpowiadających rekodom z tablicy po lewo? (Ale w tym wypadku, w przypadku usunięcia lub dodania przynajmniej jednego elementu z tabeli po lewo, będę musiał sprawdzać, czy element został usunięty lub dodany kilka tysięcy razy po prawej stronie.) Bardzo proszę o pomoc!

Ten post edytował lukesh 22.11.2011, 01:29:19
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
lukesh
post
Post #2





Grupa: Zarejestrowani
Postów: 113
Pomógł: 14
Dołączył: 25.08.2006

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


Hm, problem z warunkiem WHERE na końcu jest taki, że złączenie LEFT JOIN jest na komórce, która dla tabeli z prawej strony będzie przyjmować wartość NULL. Co prawda, dla obu tabel jest warunek WHERE courseid='$courseid', to jeśli ten warunek zapiszę na końcu tabeli, wtedy nie pobierze mi wszystkich wierszy z tabeli po lewej stronie, które spełniają ten warunek, ale wszystkie wiersze, które spełniają ten warunek naraz.
Myślę, że narazie zostawię, jak jest, a z czasem zobaczę, jak będzie to wszystko działało wraz z rozbudową serwisu. Narazie zapytanie wykojune się bardzo szybko, ale w tabelach nie ma wielu rekordów (chociaż dodałem po kilkadzesiąt tysięcy rekordków dla testów).

Zastanawia mnie jedna rzecz - czy jeśli w środku zapytanie SELECT * FROM wstawiam kolejne zapytanie w nawiasach (SELECT * FROM ...), to MySQL buferuje do pamięci całą tak wybraną tabelę z zapytania w nawiasach? Co się właściwie dzieje? Czy tworzy się wtedy jakaś tymczasowa tabela dla danego zapytania i np. przenoszone tam jest 10 tys. rekordów, które spełniają dany warunek?

Pozdrawiam! (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 17.10.2025 - 22:14