Zaprojektowałem tabele do quizzów:quizz_result and quizz. quizz ma klucz główny na ID a quizz_result klucz obcy QUIZZ_ID do ID quizzu.
Poniższe zapytanie bierze publiczne quizzy posortowane po dacie z dodatkowymi informacjami: czy bieżący użytkownik (683735) wypełnił quizz i czy wynik jest poprawny (>0) i ile osób wypełniło już ten quizz.
Zrobiłem więc prostego selecta z dwoma joinami:
[SQL] pobierz, plaintext
- SELECT
- a.*,
- COUNT(countt.QUIZZ_ID) SUMFILL
- FROM
- quizz a
- LEFT JOIN quizz_result countt
- ON countt.QUIZZ_ID = a.ID AND
- countt.QUIZZ_RESULT_ID > 0
- WHERE
- a.PUBLIC = 1
- GROUP BY
- countt.QUIZZ_ID
- ORDER BY
- DATE DESC
- LIMIT 0,10;
I dodałem indeksy do kolumn:
Quizz:
[SQL] pobierz, plaintext
- ID, (ID, DATE), PUBLIC, (PUBLIC, DATE)
i do quizz_result:
[SQL] pobierz, plaintext
- ID, (QUIZZ_ID, USER_ID), QUIZZ_ID, USER_ID, (QUIZZ_ID, QUIZZ_RESULT_ID), (QUIZZ_ID, QUIZZ_REZULT_ID, USER_ID)
Ale ciągle zapytanie trwa długo: prawie sekundę. A mam tylko 30k wierszy w QUIZZ_RESULTS i 120 w QUIZZ
Kiedy robię EXPLAIN otrzymuję:
[SQL] pobierz, plaintext
- SELECT TYPE: simple, possible KEYS: IDX_PUBLIC,DATE, rows: 34 extra: USING WHERE; USING TEMPORARY; USING filesort
- SELECT TYPE: simple, possible KEYS: IDX_QUIZZ_USER,IDX_QUIZZ_RES_RES_QUIZ,IDX_USERID,I..., rows: 1, extra: nothing here
- SELECT TYPE: simple, possible KEYS: IDX_QUIZZ_USER,IDX_QUIZ_RES_RES_QUIZZ,ID_RESULT_ID, rows: 752, extra: USING INDEX
Widze że to:
[SQL] pobierz, plaintext
- USING WHERE; USING TEMPORARY; USING filesort
może sprawiać problemy albo 752 wierszy w ostatnim wierszu, ale co dalej zrobić?
Jak zoptymalizować to zapytanie?
Edit: skróciłem zapytanie do wersji która trwa tak samo długo. Może teraz będzie łatwiej.