2011-05-30 73 views
2

Explain SQL解释SQL和查询优化

解释说,正在采取超过5秒是给我上面的查询的SQL(在phpMyAdmin)。我读到我们可以研究Explain SQL来优化查询。任何人都可以告诉这个解释SQL告诉任何事情吗?

谢谢你们。

编辑:

查询本身:

SELECT 
a.`depart` , a.user, 
m.civ, m.prenom, m.nom, 
CAST(GROUP_CONCAT(DISTINCT concat(c.id, '~', c.prenom, ' ', c.nom)) AS char) AS coordinateur, 
z.dr 
FROM `0_activite` AS a 
JOIN `0_member` AS m ON a.user = m.id 
LEFT JOIN `0_depart` AS d ON (m.depart = d.depart AND d.rank = 'mod' AND d.user_sec =2) 
LEFT JOIN `0_member` AS c ON d.user_id = c.id 
LEFT JOIN `zone_base` AS z ON m.depart = z.deprt_num 
GROUP BY a.user 

编辑2:两个表adTable structures

结构。顶部:a和底部:d

编辑3:

我想在此查询什么?

我首先想从表中0_activite获得“走”和“用户”(这是一个ID)的值。接下来,我想从0_member的ID我从0_activite通过“用户”获得人(CIV,prenom和名称)的名称,与0_member .ID匹配0_activite。用户。这里出发缺少也是身份证的部门。

所以在这一点上,我已经从两个表0_activite0_member的人离开,身份证,文明,诺姆和prenom。

接下来,我想知道哪个医生是这个出发有关,这从我得到zone_base。在0_activite0_member中出发的价值相同。

然后是棘手的部分。 0_member中的一个人可以与多个出发点相关联,并存储在0_depart中。另外,每个用户都有一个关卡,其中一个是'mod',代表主持人。现在,我想让所有在第一位用户所在位置的主持人都能够再次获得0_member的名称。我也有一个可变的user_sec,但这在这方面可能不那么重要,尽管我不能忽视它。

这是什么使查询一个棘手的一个。 0_member的存储ID,用户名,+一个离去,0_depart是存储用户的所有的出发,一行每个离去,0_activite存储着一些其他的东西,我想那些有关通过0_activite,其余用户ID。

希望我已经明确。如果我不是,请让我知道,我会再次尝试编辑这篇文章。

很多人再次感谢。

+3

在这里查看查询也会非常有帮助。 – 2011-05-30 22:23:15

+1

只要你显示表结构(包含数据类型)和查询 – Ibu 2011-05-30 22:34:03

+0

@will A,@,你会得到很好的解释:) – 2011-05-30 22:49:21

回答

2
从这里的其他人提供的几个答案

除了一个关键,它可能有助于更好GROUP柱也应该被收录了解查询中的“我想要什么”。由于您在另一个问题中接受了我最近的回答,因此您可以使用按部门信息应用的过滤器。

您的查询是通过rank ='mod'和user_sec = 2在Department表中执行LEFT连接。是否您的总体意图是显示0_activite表中的所有记录,以及0_Depart表的有效连接的无关性......如果与0_Depart表匹配,你只关心'mod'和2个值?

如果你只关心那些具有'mod'和2条件的0_depart特定关联的人,我将首先颠倒从THIS表开始的查询,然后加入其余部分。

通过关系或标准在表上拥有键始终是性能优势(vs没有索引)。

开始您的查询与任何将您的最小集FIRST,然后加入到其他表。

从你的问题澄清...我会从最内心开始...它是谁和他们与哪些部门相关...然后获得主持人(从部门的条件)...然后得到实际主持人的姓名信息...终于出到您zone_base基于主持人的部门的医生......我

select STRAIGHT_JOIN 
     DeptPerMember.* 
     Moderator.Civ as ModCiv, 
     Moderator.Prenom as ModPrenom, 
     Moderator.Nom as ModNom, 
     z.dr 
    from 
     (select 
       m.ID, 
       m.Depart, 
       m.Civ, 
       m.Prenom, 
       m.Nom 
      from 
       0_Activite as a 
       join 0_member m 
        on a.User = m.ID 
        join 0_Depart as d 
         on m.depart = d.depart ) DeptPerMember 

     join 0_Depart as DeptForMod 
     on DeptPerMember.Depart = DeptForMod.Depart 
     and DeptForMod.rank = 'mod' 
     and DeptForMod.user_sec = 2 

     join 0_Member as Moderator 
      on DeptForMod.user_id = Moderator.ID 

      join zone_base z 
       on Moderator.depart = z.deprt_num 

注意如何tier'd的查询来获取每一个部分,并加入到下一个和下一个。我正在根据以前的结果构建链,并带有明确的“别名”参考以澄清内容。现在,您可以通过不同的“别名”引用从任何级别获取任何相应的元素...

+0

谢谢@DRapp,我非常感谢您的帮助。我试图通过编辑上面的帖子来解释我想要的,让我知道你是怎么看到的。再次感谢。 – 2011-05-31 21:17:30

+1

@Jeremy Roy,修改并包含查询.. – DRapp 2011-05-31 22:19:00

+0

非常感谢@DRapp。是不是这种方法,除非我错过了一些问题,如:表0_activite列出的东西,活动。现在不是所有的成员都会有活动。我首先获取0_activite表,以查看哪些用户有活动,然后获取有关该用户的相关信息(如姓名,主持人姓名,博士等)。你在这里怎么想?另外,除非我需要,我可以删除'where m.ID = AnIDIfYouWantOnlyOnePerson',不是吗? – 2011-05-31 22:24:42

2

EXPLAIN的输出向我们展示了列出的第一个和第三个表(一个& d)在执行此查询时没有任何由数据库引擎使用的索引。关键字列对于两者都是NULL - 这是一个耻辱,因为它们都是'大'表(好吧,它们并不是很大,但与其余表格相比,它们是大的'uns')。

从查询情况来看,在user0_activite指数和0_depart(depart, rank, user_sec)指数将在一定程度上提高了性能。

+0

谢谢@will A.嗯,这很奇怪,因为我确实在这些列中有索引。可能我没有把这些索引放在“正确”的方式?我编辑了原始帖子以添加新图片。 – 2011-05-31 20:53:44

+1

Jeremy没问题。你的'0_depart'索引不是'(depart,rank,user_sec)' - 我认为这个索引值得一试。 – 2011-06-01 01:39:58

+0

你的意思是结合这些3 @ Will的指数? – 2011-06-01 13:42:10

2

您可以看到列keykey_len为空,这意味着它不使用possible_keys列中的任何键。所以表ad都在扫描所有的行。 (在行列中检查更大的数字,你希望这个更小)。

要处理0_depart: 确保您有一个关键字(d.depart, d.rank,d.user_sec),它们是0_depart连接的一部分。

为了应对0_activite: 我还不能肯定,但因此需要对a.user

+0

谢谢@ weired00。好吧,这很奇怪,因为我在这些列中有索引。可能我没有把这些索引放在“正确”的方式?我编辑了原始帖子以添加新图片。 – 2011-05-31 20:56:52