Jedna uwaga. Do moich zapytan podanych we wczesniejszym poscie wkradl sie blad. Ponizsze zapytanie jest zle:
SELECT * FROM uzytkownicy WHERE (grupy & $grupy) > 0
powinno byc:
SELECT * FROM uzytkownicy WHERE (grupy & $grupy) = $grupy
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:
CREATE TABLE `users` (
`id` mediumint(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(20) collate utf8_polish_ci NOT NULL,
`pass` varchar(40) collate utf8_polish_ci NOT NULL,
`groups` int(10) UNSIGNED NOT NULL DEFAULT '0',
`homedir` varchar(30) collate utf8_polish_ci NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `groups` (`groups`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci
i wypelnilem je przypadkowymi danymi. Jesli chodzi o name, pass i homedir, dane te pobralem czytajac plik avi

, 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:
SELECT SQL_NO_CACHE * FROM users WHERE groups & $liczba = $liczba LIMIT 30
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.