Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> wiadomości - optymalizacja
nospor
post
Post #1





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Mam takie tabele

  1. CREATE TABLE `message` (
  2. `ID` int UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `FK_MESSAGE` int UNSIGNED NOT NULL DEFAULT 0 comment ,
  4. `FK_LAST_MESSAGE` int UNSIGNED NOT NULL DEFAULT 0 comment 'Id ostatniej odpowiedzi. wskazuje na siebie gdy nie ma odpowiedzi',
  5. `MESSAGE` text NOT NULL,
  6. `FK_CUSER` int NOT NULL COMMENT 'Kto utworzyl',
  7. PRIMARY KEY (`ID`),
  8. KEY `FK_MESSAGE` (`FK_MESSAGE`),
  9. KEY `FK_CUSER` (`FK_CUSER`),
  10. KEY `FK_LAST_MESSAGE` (`FK_LAST_MESSAGE`)
  11. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  12.  
  13. CREATE TABLE `message_user` (
  14. `FK_USER` int UNSIGNED NOT NULL comment 'Id usera',
  15. `FK_MESSAGE` int UNSIGNED NOT NULL comment 'Id wiadomosci',
  16. PRIMARY KEY (`FK_USER`,`FK_MESSAGE`)
  17. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  18.  

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
  1. SELECT cm.ID, cm.MESSAGE,cm.IP,cm.CDATE,cm.COUNT_MESSAGES
  2. FROM message cm
  3. LEFT JOIN message_user cmu ON (cmu.FK_MESSAGE=cm.ID AND cmu.FK_USER=4)
  4. WHERE cm.FK_MESSAGE = 0 AND (cm.FK_CUSER = 4 OR cmu.FK_USER IS NOT NULL)
  5. 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

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ć.
Powód edycji: [nospor]:
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
nospor
post
Post #2





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Jak rozumiem przy zakładaniu wiadomości użytkownik wybiera do jakich użytkowników jest kierowana wiadomość, nie dyskutuję, bo to funkcjonalność, widocznie tak ma być
Tak, tak ma byc (IMG:style_emoticons/default/smile.gif)

ad1) Bawiłem się już i taką kombinacją - nic to nie dało
ad2) Zrobiłem to celowo. Dzięki mojemu zastosowaniu unikam duplikacji głównego rekordu, przy kilku wpisach w tabeli wiążącej dla danej wiadomości
ad3) No niestety nic to nie dało. Mało tego, to rozwiązanie jest jeszcze gorsze, gdy zmula zapytanie nawet wówczas gdy wawalę z OR ten pierwszy warunek na FK_CUSER. Gdy zostawię joina zamiast EXISTS, to po wywaleniu FK_CUSER z OR zapytanie śmiga jak ta lala.

Kombinuj dalej. Chętnie wysłucham jeszcze jakiś propozycji. Szczerze powiedziawszy gdy pokazałeś EXISTS to już miałem cień nadziei że zadziała.
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: 14.09.2025 - 16:35