![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 150 Pomógł: 3 Dołączył: 15.08.2007 Ostrzeżenie: (0%) ![]() ![]() |
Mam taki zestaw tabel:
użytkownik (z uzytkownikami systemu) grupy (grupy do ktorych moze zapisac sie uzytkownik) (np A, B, C , D , E ...) uzytkownicy_grupa (relacjz zawierająca informacje o grupac do ktorych jest zapisany użytkownik) załóżmy że użytkowników jest milion a grup 10-20 więc wydajność ma znaczenie. schamt jest taki użytkownik 1 - N użytkownicy_grupa N <- 1 grupy Jak najwydajniej zapytać się o użytkowników należących do grupy A, B i C: Przychodzą mi do głowy 3 rozwiązania po 1: - totalnie lame - umieścic w tabeli użytkownicy spis grup po przecinku i użyć LIKE po 2: - wykorzystanie zmiennej typu array - to też nie wygląda na idealne rozwiązanie ponieważ jest ograniczenie przy przeszukiwaniu zmiennych array, można jedynie użyć any lub all (+ na PostgreSQL napisano Tip: Arrays are not sets; searching for specific array elements may be a sign of database misdesign. Consider using a separate table with a row for each item that would be an array element. This will be easier to search, and is likely to scale up better to large numbers of elements. ) po 3: - używanie subselecta na zasadzie
Ma ktoś jakieś lepsze rozwiązania lub umie uzasadnić które wybrać i dlaczego? Ten post edytował kris2 21.08.2007, 19:40:38 |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 121 Pomógł: 15 Dołączył: 19.07.2007 Ostrzeżenie: (0%) ![]() ![]() |
Jedna uwaga. Do moich zapytan podanych we wczesniejszym poscie wkradl sie blad. Ponizsze zapytanie jest zle:
powinno byc:
W pierwszym przypadku zostana znalezieni wszyscy uzytkownicy ktorzy naleza do przynajmniej jednej z grup (a nie wszystkich)! Ciekaw bylem wydajnosci takiego rozwiazania i sam zrobilem troche testow. Stworzylem przykladowa tabele:
i wypelnilem je przypadkowymi danymi. Jesli chodzi o name, pass i homedir, dane te pobralem czytajac plik avi (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) , groups byly losowo generowane, active co druga jest 1. Wstawilem 1,5 mln rekordow. Tabela zajmuje:170MB, z indeksami prawie 200MB. Co sie okazalo to to ze dlugosc wyszukiwania uzytkownikow nalezacych do wybranych grup zalezy od tego ile grup chcemy sprawdzic. Nie wiem czemu tak sie dzieje, moze ktos ma jakis pomysl. Testy przeprowadzilem w nastepujacy sposob: dla kazdej mozliwej liczby bitow(1-31) wykonywalem 10 zapytan:
gdzie $liczba to losowo wygenerowana liczba w ktorej n bitow jest zapalonych (to tak jakbysmy szukali user wsrod n losowo wybranych grup), mierzylem czas wykonywania tych zapytan i potem obliczylem srednia. Oto wyniki: Kod Ilosc bitow Sredni czas(s) --------------------------------- 1 0.00074770450592 2 0.000751495361328 3 0.000946569442749 4 0.0039412021637 5 0.0040956735611 6 0.00505304336548 7 0.00831155776978 8 0.0105215072632 9 0.0200308084488 10 0.0367336988449 11 0.0835324525833 12 0.147039031982 13 0.276187181473 14 0.507218337059 15 1.06423690319 16 1.53951747417 17 1.59646685123 18 1.64317190647 19 1.67781071663 20 1.71348867416 21 1.56421909332 22 1.59005527496 23 1.62178874016 24 1.64297554493 25 1.67281501293 26 1.65174326897 27 1.57270855904 28 1.6054520607 29 1.62569227219 30 1.66454772949 31 1.6705922842 Jak widac czas wykonywania zapytania na poczatku rosnie wykladniczo. Pozniej najprawdopodobniej zaczely coraz lepiej dzialac mechanizmy cacheujace linux'a. Testy przeprowadzalem na kompie: AMD Sempron 2500+ pamiec 1GB RAM dysk 160GB SATA 8MB Cache OS: Kubuntu 7.04 W czasie wykonywania testu zajetosc czasu procesora byla maksymalna. Komp sluzy do uzytku domowego, wiec w czasie testow bylo otwartych sporo innych aplikacji, ale staralem sie wtedy nic nie robic (nawet nie ruszalem myszka) wiec wyniki powinny byc w miare wiarygodne. Nie wiem czy to jest optymalne rozwiazanie, warto by jeszcze sprawdzic jak sie sprawdzi moje wczesniejsze rozwiazanie (z grupowaniem) i jakie beda osiaga przy wykorzystaniu pola typu BITFIELD. Ten post edytował osiris 23.08.2007, 15:09:16 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 5.10.2025 - 15:20 |