Запрос кросс-таблицы, включая 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 в вашем запросе, которые будут намного быстрее.
Надеюсь, вы сделаете это намного быстрее.