2014-09-04 105 views
0

我正在构建一个查询,该查询将在我的网站上为配置文件生成预览。在mysql中包含COUNT和LEFT JOINS的交叉表查询

该查询涉及多个表,获得某些信息,即姓名和COUNT()以用于统计某个特征,即他们有多少喜欢。

下面的查询是永久执行。我看到的其中一个问题是我使用了LEFT JOINS来获取所有数据。所以首先,任何人都可以帮助我了解如何选择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' 

假设所有的表中的数据是正确的,如果你想它要求它,我都会给你做。

P.s.在添加/* AMBITIONS COMPLETED */之前,查询似乎运行正常。我认为它是因为它包含一个双LEFT JOIN。

在此先感谢

+0

没有你的数据模型的详细知识(特别是哪些领域进行索引),这是一个猜谜游戏,为什么它需要很长的时间。你看过执行计划吗? – 2014-09-04 09:02:31

+0

我刚刚抨击了mysql代码,看是否有人可以发现语义或语法中的任何错误。索引的唯一字段是主键,通常是每个表的IDS。我没有听说过执行计划。请告诉。谢谢 – cwiggo 2014-09-04 09:05:21

+0

对不起,MySQL使用术语“解释计划”(就像Oracle);从这里开始http://dev.mysql.com/doc/refman/5。7/EN /执行计划,information.html – 2014-09-04 12:41:25

回答

1

后的研究时间我遇到另一个查询技术来检索以下数据:

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' 

我希望这个答案是有一定的帮助开发者谁试图访问,总结和整理,从他们的数据库表的统计信息。

感谢评论

0

如果查询得到追加表x_table8和x_table9后慢那么我认为x_table9表中包含大量的数据。尽量避免LEFT JOIN。要使用LEFT JOIN,如果你想从x_table8得到一条记录,即使它没有在x_table9表中有关联的记录,那么只能使用LEFT JOIN,其他明智的JOIN可以为你做更快的工作。

正如你所说你正在使用它来生成一个配置文件,那么我会建议使用JOIN作为配置文件ID没有数据的表,这对我来说意味着更少。

如果你不能避免LEFT JOIN尝试使用临时表并在查询中使用那些TEMP TABLES将会快得多。

希望你能做得更快。

+0

你说得对,表9比其他人更多的行。总计:93我会取代所有LEFT使用连接JOIN,看看它是否有差别。由于 – cwiggo 2014-09-04 09:09:46

+0

可悲的是它不有所作为:( – cwiggo 2014-09-04 09:26:04

+0

LEFT JOIN x_table8 AO ON(u.id = ao.profile_id) LEFT JOIN x_table9是 ON(ao.ambition_id = am.id和am.complete = 1) 对于这种尝试使用个人资料的ID来创建一个临时表,并使用该温度表在主查询中。我已经使用TEMP表之前,他们的确会影响查询的速度。 – 2014-09-04 09:34:05