Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> SELECT WHERE NOT IN - podzapytanie, Strasznie wolno...
geogis
post
Post #1





Grupa: Zarejestrowani
Postów: 30
Pomógł: 0
Dołączył: 12.03.2005

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


Witam,

Mam problem z pewnym zadaniem. Mam jedno rozwiązanie ale jakoś mnie to nie zadowala.

Chodzi o takie zapytanie:

  1. SELECT * FROM users u WHERE u.image<>'' AND u.user_id<>'15' AND u.user_id NOT IN (SELECT v.user_id FROM voting v WHERE v.voter_id='15') ORDER BY RAND() LIMIT 1


w tabeli 'users' jest kilka tysięcy wpisów a w voting jest tez kilka tysiecy (ale bedzie o wiele wiecej - bo tu zapisywane sa dane zwiazane z pewnym glosowaniem na stronie i kazdy użytkownik glosuje po setki razy). Takie zapytanie niestety jest tak pamięciożerne że siada mi cała strona.

Zmieniłem to na takie coś że najpierw zbieram dane do tabeli z tego zapytania:

  1. SELECT v.user_id FROM voting v WHERE v.voter_id='15'


i podstawiam do zapytania gotową listę użytkowników:

  1. SELECT * FROM users u WHERE u.image<>'' AND u.user_id<>'15' AND u.user_id NOT IN ($tablica_uzytkownikow) ORDER BY RAND() LIMIT 1


ale wyczytałem na róznych forach dyskusyjnych że NOT IN generalnie nie jest szybkie i ze jak $tabela_uzytkownikow bedzie zawierac tysiace wartosci to moze powodować to duże opóźnienia...

Jakiś pomysł na inne rozwiazanie?

Generalnie wyglada to tak że uzytkownik A dostaje losowego użytkownika do glosowania (powidzmy ze glosuje na to czy mu sie podoba czy nie). Ma dwie odpowiedzi. TAK lub NIE. Po zaglosowaniu zapisywane jest do bazy do tabeli VOTING voter_id (czyli ten uzytkownik A), user_id (czyli ta osoba na która glosowano) no i sama odpowiedz.

Po zaglosowaniu trzeba wylosowac nastepnego uzytkownika do głosowania, ale oczywiscie nie moze to być osoba na którą juz glosowalismy

Tabele mamy takie:

USERS:
user_id
image

VOTING
voter_id
user_id


Z gory dzieki za pomysły!
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Pilsener
post
Post #2





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

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


Moim zdaniem nie da się tego tak wprost zoptymalizować, lecz nie jesteśmy bezsilni:
- losujemy ID jakiegoś usera i sprawdzamy, czy możemy na niego głosować - jeśli nie losujemy następne ID (to będzie dobre przy dużej liczbie userów gdy wiemy, że user A nie jest w stanie zagłosować na więcej niż kilka procent pozostałych userów)
- zawężamy zakres order by rand() losując dwuetapowo, najpierw losujemy jakiś przedział rekordów (np. 6700<ID<6800) i dopiero na nich wykonujemy order by rand

Pisałem o tym także tutaj:
http://forum.php.pl/index.php?s=&showt...st&p=817847
Go to the top of the page
+Quote Post

Posty w temacie


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 Aktualny czas: 16.10.2025 - 06:40