views:

316

answers:

4

Hello,

I'm designing a project for quizzes and quizz results. So I have two tables: quizz_result and quizz. quizz has primary key on ID and quizz_result has foreign key QUIZZ_ID to quizz identity.

Query below is designed to take public quizzes ordered by date with asociated informations: if current user (683735) took this quizz and has a valid result (>0) and how many people filled this quizz till this point in time.

So i did this simple query with two left joins:

select     
  a.*,  
  COUNT(countt.QUIZZ_ID) SUMFILL
from 
  quizz a
  left join quizz_result countt
    on countt.QUIZZ_ID = a.ID 
group by 
   a.ID

And added indexes on these columns: Quizz:

ID, (ID, DATE), PUBLIC, (PUBLIC, DATE)

And on quizz_result:

ID, (QUIZZ_ID, USER_ID), QUIZZ_ID, USER_ID, (QUIZZ_ID, QUIZZ_RESULT_ID)

But still when I do query it takes like about one minute. And i have only 34k rows in QUIZZ_RESULTS and 120 rows in QUIZZ table.

When I do EXPLAIN on this query I get this:

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

And I don't know what to do to optimise this query. I see this:

Using where; Using temporary; Using filesort

But still I don't know how to get this better, or maybe number of rows in last select is to hight? 752?

How can I optimise this query?

EDIT: I've upadated query to this one with only one left join because it has the same long execution time.

EDIT2: I did remove everything to and thats it: this simple select with one query takes 1s to execute. How to optimise it?

A: 

What about an index on (USER_ID, QUIZZ_ID, QUIZZ_RESULT_ID), since they're all AND'd together?

Kev
I think that you are right that should help, but I've added it to this table but unfortunately times are the same. So maybe it would be the next optimisation. Still there is something big and bad in this query
tomaszs
It's still slow with just one left join? I don't have a lot of experience, but that doesn't seem right. Are there many other queries that take a long time that look like they shouldn't? Have you changed any of the database engine parameters (threads, shared memory, etc.) from the defaults? I guess before those, check that you actually set up a foreign key restriction on quizz_result.
Kev
+1  A: 

Try taking some of those additional conditions out of your joins. Moving them to the where clause can sometimes help. Also, consider putting the core joins into their own subquery and then limiting that with a where clause.

Sonny Boy
I try but without success can you be more descriptive?
tomaszs
Since my original answer your query has changed some and I don't think my answer is valid any longer. Take a look at the indexes you have on both of those tables. Make sure you have indexes on all of the columns you're joining by. Whenever possible, join on unique values within each table (e.g. Primary and Foreign Keys).
Sonny Boy
A: 

I've changed it to this:

select     
  a.*,  
  COUNT(a.ID) SUMFILL
from 
  quizz a
  left join quizz_result countt
    on countt.QUIZZ_ID = a.ID 
group by 
   a.ID

And it's good now.

tomaszs
A: 

Try this:

SELECT  q.*,
        (
        SELECT  COUNT(*)
        FROM    quizz_results qr
        WHERE   qr.quizz_id = q.id
        ) AS total_played,
        (
        SELECT  result
        FROM    qr.quizz_id = q.id
                AND user_id = 683735
        ) AS current_user_won
FROM    quizz q
Quassnoi