解释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:两个表a
和d
的
结构。顶部:a
和底部:d
编辑3:
我想在此查询什么?
我首先想从表中0_activite
获得“走”和“用户”(这是一个ID)的值。接下来,我想从0_member
的ID我从0_activite
通过“用户”获得人(CIV,prenom和名称)的名称,与0_member
.ID匹配0_activite
。用户。这里出发缺少也是身份证的部门。
所以在这一点上,我已经从两个表0_activite
和0_member
的人离开,身份证,文明,诺姆和prenom。
接下来,我想知道哪个医生是这个出发有关,这从我得到zone_base
。在0_activite
和0_member
中出发的价值相同。
然后是棘手的部分。 0_member
中的一个人可以与多个出发点相关联,并存储在0_depart
中。另外,每个用户都有一个关卡,其中一个是'mod',代表主持人。现在,我想让所有在第一位用户所在位置的主持人都能够再次获得0_member
的名称。我也有一个可变的user_sec,但这在这方面可能不那么重要,尽管我不能忽视它。
这是什么使查询一个棘手的一个。 0_member的存储ID,用户名,+一个离去,0_depart是存储用户的所有的出发,一行每个离去,0_activite
存储着一些其他的东西,我想那些有关通过0_activite
,其余用户ID。
希望我已经明确。如果我不是,请让我知道,我会再次尝试编辑这篇文章。
很多人再次感谢。
除了一个关键,它可能有助于更好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的查询来获取每一个部分,并加入到下一个和下一个。我正在根据以前的结果构建链,并带有明确的“别名”参考以澄清内容。现在,您可以通过不同的“别名”引用从任何级别获取任何相应的元素...
谢谢@DRapp,我非常感谢您的帮助。我试图通过编辑上面的帖子来解释我想要的,让我知道你是怎么看到的。再次感谢。 – 2011-05-31 21:17:30
@Jeremy Roy,修改并包含查询.. – DRapp 2011-05-31 22:19:00
非常感谢@DRapp。是不是这种方法,除非我错过了一些问题,如:表0_activite列出的东西,活动。现在不是所有的成员都会有活动。我首先获取0_activite表,以查看哪些用户有活动,然后获取有关该用户的相关信息(如姓名,主持人姓名,博士等)。你在这里怎么想?另外,除非我需要,我可以删除'where m.ID = AnIDIfYouWantOnlyOnePerson',不是吗? – 2011-05-31 22:24:42
EXPLAIN的输出向我们展示了列出的第一个和第三个表(一个& d)在执行此查询时没有任何由数据库引擎使用的索引。关键字列对于两者都是NULL - 这是一个耻辱,因为它们都是'大'表(好吧,它们并不是很大,但与其余表格相比,它们是大的'uns')。
从查询情况来看,在user
上0_activite
指数和0_depart
上(depart, rank, user_sec)
指数将在一定程度上提高了性能。
谢谢@will A.嗯,这很奇怪,因为我确实在这些列中有索引。可能我没有把这些索引放在“正确”的方式?我编辑了原始帖子以添加新图片。 – 2011-05-31 20:53:44
Jeremy没问题。你的'0_depart'索引不是'(depart,rank,user_sec)' - 我认为这个索引值得一试。 – 2011-06-01 01:39:58
你的意思是结合这些3 @ Will的指数? – 2011-06-01 13:42:10
您可以看到列key
和key_len
为空,这意味着它不使用possible_keys
列中的任何键。所以表a
和d
都在扫描所有的行。 (在行列中检查更大的数字,你希望这个更小)。
要处理0_depart
: 确保您有一个关键字(d.depart, d.rank,d.user_sec
),它们是0_depart连接的一部分。
为了应对0_activite
: 我还不能肯定,但因此需要对a.user
谢谢@ weired00。好吧,这很奇怪,因为我在这些列中有索引。可能我没有把这些索引放在“正确”的方式?我编辑了原始帖子以添加新图片。 – 2011-05-31 20:56:52
在这里查看查询也会非常有帮助。 – 2011-05-30 22:23:15
只要你显示表结构(包含数据类型)和查询 – Ibu 2011-05-30 22:34:03
@will A,@,你会得到很好的解释:) – 2011-05-30 22:49:21