Запрос кросс-таблицы, включая COUNT и LEFT JOINS в MySQL

Я создаю запрос, который сгенерирует предварительный просмотр профиля на моем веб-сайте.

Запрос включает несколько таблиц, получая определенную информацию, например, имя и COUNT() для статистики определенного профиля, то есть сколько лайков у них есть.

Приведенный ниже запрос выполняется вечно. Одна из проблем, которые я вижу, состоит в том, что я использую ЛЕВЫЕ СОЕДИНЕНИЯ для получения всех данных. Поэтому, прежде всего, кто-нибудь может мне помочь, как выбрать, какой JOIN я использую для какого запроса.

Кроме этого, кто-нибудь может увидеть, что я делаю не так. Что нужно так долго, чтобы выполнить.

Вот запрос:

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'

Предположим, что все данные таблицы верны, если вы хотите, чтобы они запрашивались, и я выполню это за вас.

Ps, прежде чем я добавил /* AMBITIONS COMPLETED */ запрос, кажется, работает нормально. Я думаю, потому что он содержит двойное левое соединение.

заранее спасибо

2 ответа

Решение

После нескольких часов исследований я наткнулся на другую технику запросов для получения следующих данных:

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
)

Эти данные собраны из нескольких таблиц из моей базы данных. Как видите, скорость запроса очень высокая. В любом случае лучше, чем зависать!

Изменение в запросе было следующим. Я приведу фрагмент, так как это в основном повторяющийся код для разных таблиц:

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'

Я надеюсь, что этот ответ поможет разработчикам, которые пытаются получить доступ, обобщить и сопоставить статистику из своих таблиц базы данных.

Спасибо за комментарий

Если запрос стал медленным после добавления таблицы x_table8 и x_table9, то я думаю, что таблица x_table9 содержит большие данные. Старайтесь избегать LEFT JOIN. Чтобы использовать LEFT JOIN, если вам нужна запись из x_table8, даже если она не имеет связанных записей в таблице x_table9, используйте только LEFT JOIN, а другой мудрый JOIN может сделать эту работу гораздо быстрее.

Поскольку вы сказали, что используете это для создания профиля, я предлагаю использовать JOIN, так как таблицы без данных для идентификатора профиля будут для вас значить меньше.

Если вы не можете избежать LEFT JOIN, попробуйте использовать временные таблицы и использовать те TEMP TABLES в вашем запросе, которые будут намного быстрее.

Надеюсь, вы сделаете это намного быстрее.

Другие вопросы по тегам