Search code examples
mysqljoincountleft-joinright-join

Cross table query including COUNT and LEFT JOINS in mysql


I am building a query that will generate a preview for a profile on my website.

The query involves several tables, getting certain information, i.e. a name and COUNT()'s for statistics of a certain profile i.e. how many likes they have.

The query below is taking forever to execute. One of the problems I see is that I'm using LEFT JOINS to get all the data. So first of all can anybody help me on how to choose what JOIN I use for what query.

Other than that, can anyone see what I'm doing wrong. Whats taking it so long to execute.

Here is the query:

SELECT  u.id AS id, 
        u.about AS About, 
        CONCAT(u.fn,' ',u.ln) AS Fullname, 
        u.username AS Username, 
        i.image AS Image,
        COUNT(DISTINCT a.id) AS Contacts,
        COUNT(DISTINCT ul.id) AS Thumbs,
        u.views AS Views,
        COUNT(DISTINCT o.id) AS TrybesStarted,
        COUNT(DISTINCT ti.id) AS TrybesJoined,
        COUNT(DISTINCT ai.id) AS AmbitionsSupporting,
        COUNT(DISTINCT am.id) AS AmbitionsCompleted,
        COUNT(DISTINCT sp.id) AS Posts
FROM x_table1 u
    /* PIC */
    LEFT JOIN x_table2 i
    ON u.id = i.user_id
    /* CONTACTS */
    LEFT JOIN x_table3 a
    ON (u.id = a.to  AND a.accepted = 1 OR u.id = a.from AND a.accepted = 1)
    /* THUMBS UP */
    LEFT JOIN x_table4 ul 
    ON (u.id = ul.profile_id)
    /* TRYBES STARTED */
    LEFT JOIN x_table5 o 
    ON (u.id = o.profile_id)
    /* TRYBES JOINED */
    LEFT JOIN x_table6 ti 
    ON (u.id = ti.to AND ti.accepted = 1)

    /* AMBITIONS SUPPORTING */
    LEFT JOIN x_table7 ai
    ON (u.id = ai.to AND ai.accepted = 1)

    /* AMBITIONS COMPLETED */
    LEFT JOIN x_table8 ao
    ON (u.id = ao.profile_id)
    LEFT JOIN x_table9 am
    ON (ao.ambition_id = am.id AND am.complete = 1)

    /* POSTS */
    LEFT JOIN x_table10 sp 
    ON (u.id = sp.profile_id)

WHERE u.id = '1234userid'

Assume all table data is correct, if you would like it request it and I'll get it done for you.

P.s. Before I added the /* AMBITIONS COMPLETED */ the query seemed to run fine. I think its because it contains a double LEFT JOIN.

Thanks in advance


Solution

  • After hours of research I came across another query technique to retrieve the following data:

    Array
    (
        [ID] => useridentifier
        [ABOUT] => ABOUT :)
        [NAME] => Chris m
        [REGISTERED] => 2013-10-21 12:54:50
        [USERNAME] => Cwiggo
        [VIEWS] => 3
        [IMAGE] => useridentifier
        [AWARDS] => 0
        [TRYBANK] => 1
        [USER_CONTACTS] => 6
        [USER_THUMBS_UP] => 6
        [TRYBES_STARTED] => 28
        [TRYBES_JOINED] => 13
        [USER_POSTS] => 8
        [AMBITIONS_STARTED] => 40
        [AMBITIONS_JOINED] => 13
        [AMBITIONS_COMPLETE] => 1
        [Retreival] => 0.00026202201843262
    )
    

    This data is collected from several tables from my database. As you can see, the query speed is very quick. Better than a hang anyway!

    The change to the query was as follows. I'll provide a snippet as it's basically repeated code for different tables:

    SELECT u.id AS ID, 
        u.registered                AS REGISTERED, 
        u.x_account_username        AS USERNAME,
        COALESCE(uc.cnt, 0)         AS USER_CONTACTS,
        COALESCE(ut.cnt, 0)         AS USER_THUMBS_UP,
    
        FROM x_user u
    
        #IMAGES
        LEFT JOIN x_user_images images  ON u.id = images.user_id
    
        #CONTACTS
        LEFT JOIN 
          ( SELECT `to`,accepted,`from`, COUNT(*) AS cnt FROM
            x_allies
            GROUP BY `to`) uc
        ON (u.id = uc.to AND uc.accepted = 1 OR u.id = uc.from AND uc.accepted = 1)
    
        #THUMBS UP
        LEFT JOIN 
          ( SELECT user_id, COUNT(*) AS cnt FROM
            x_user_likes
            GROUP BY user_id ) ut
        ON u.id = ut.user_id
    WHERE u.id = 'useridentifier'
    

    I hope this answer is of some help for developers who are trying to access, summarise and collate statistics from their database tables.

    Thanks for commenting