CREATE TABLE `message` ( `ID` int UNSIGNED NOT NULL AUTO_INCREMENT, `FK_MESSAGE` int UNSIGNED NOT NULL DEFAULT 0 comment , `FK_LAST_MESSAGE` int UNSIGNED NOT NULL DEFAULT 0 comment 'Id ostatniej odpowiedzi. wskazuje na siebie gdy nie ma odpowiedzi', `MESSAGE` text NOT NULL, `FK_CUSER` int NOT NULL COMMENT 'Kto utworzyl', PRIMARY KEY (`ID`), KEY `FK_MESSAGE` (`FK_MESSAGE`), KEY `FK_CUSER` (`FK_CUSER`), KEY `FK_LAST_MESSAGE` (`FK_LAST_MESSAGE`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `message_user` ( `FK_USER` int UNSIGNED NOT NULL comment 'Id usera', `FK_MESSAGE` int UNSIGNED NOT NULL comment 'Id wiadomosci', PRIMARY KEY (`FK_USER`,`FK_MESSAGE`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Mamy tabelę wiadomości oraz tabelę wiążącą, która mówi, że tę wiadomość może zobaczyć taki a taki user.
Wiadomość może też widziec ten, kto ją utworzył (FK_CUSER)
No i mam zapytanie pobierające wiadomosci
SELECT cm.ID, cm.MESSAGE,cm.IP,cm.CDATE,cm.COUNT_MESSAGES FROM message cm LEFT JOIN message_user cmu ON (cmu.FK_MESSAGE=cm.ID AND cmu.FK_USER=4) WHERE cm.FK_MESSAGE = 0 AND (cm.FK_CUSER = 4 OR cmu.FK_USER IS NOT NULL) ORDER BY cm.FK_LAST_MESSAGE DESC LIMIT 5
Czyli pobieram wiadomosci jakie może widziec użytkownik 4
W bazie mam 500tys rekordów. Wszystko smiga do czasu dodania OR cmu.FK_USER IS NOT NULL czyli sprawdzeniu tabeli wiążącej. EXPLAIN daje:
Kod
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE cm index FK_MESSAGE,FK_CUSER FK_LAST_MESSAGE 4 \N 35 Using where
1 SIMPLE cmu eq_ref PRIMARY PRIMARY 8 cm.ID,const 1 Using where; Using index
1 SIMPLE cm index FK_MESSAGE,FK_CUSER FK_LAST_MESSAGE 4 \N 35 Using where
1 SIMPLE cmu eq_ref PRIMARY PRIMARY 8 cm.ID,const 1 Using where; Using index
Gdy dodam tego OR to zapytanie wykonuje się 2 sekundy. Idzie jakoś to przyspieszyc? Nie widzę za bardzo jakie mam tu dodać dodatkowe indeksy.
Przed chwilą wpadłem na pomysł, że wystarczy iż zamienie
cm.FK_CUSER = 4 OR cmu.FK_USER IS NOT NULL
na
cmu.FK_USER IS NOT NULL
czyli wywale sprawdzanie autora wiadomosci, a autora dodam do tabeli wiążącej. Wówczas zapytanie znowu śmiga. Wolałbym jednak tego rozwiązania nie stosować.