如何解决解释SQL和查询优化
| 解释一下花费超过5秒钟的查询的SQL(在phpmyadmin中),我得到了上面的提示。我读到我们可以研究ѭ0来优化查询。谁能说清楚这个Explain 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
中获取\'depart \'和\'user \'的值(这是一个ID)。接下来,我想通过将0_activite
.user与ѭ7id.id匹配来从0_activite
中通过\'user \'获得我的ID的0_member
中的人名(civ,prenom和name)。在这里出发缺少部门,这也是一个ID。
因此,在这一点上,我从一个tables6ѭ和0_member
两个表中分离了一个人的id,civ,nom和prenom。
接下来,我想知道哪个博士与这个离开有关,这是我从zone_base
得到的。 part6ѭ和0_member
中depart的值相同。
然后是棘手的部分。 0_member
中的一个人可以与多个部门关联,并将其存储在0_depart
中。同样,每个用户都有一个级别,即“ mod”之一,它代表主持人。现在,我想让所有主持人离开第一个用户所在的地方,然后再次从0_member
获得那些主持人的名字。我也有一个变量user_sec,但这在上下文中可能不太重要,尽管我不能忽略它。
这就是使查询变得棘手的原因。 0_member存储id,用户名,+一个部门,0_depart存储所有用户部门,每个部门一行,而0_activite
存储其他东西,我想通过0_activite
和其余的userid关联这些东西。
希望我已经清楚了。如果不是,请告诉我,我将再次尝试编辑此帖子。
非常感谢。
解决方法
除了此处其他人提供的一些答案之外,它可能有助于更好地理解查询中的“我想要什么”。当您在另一个问题中接受了我的近期答复时,您已按部门信息应用了过滤器。
您的查询正在通过Rank = \'mod \'和user_sec = 2在Department表中进行LEFT连接。您的总体意图是显示0_activite表中的所有记录吗?REGARDLESS有效地连接到0_Depart表...,如果与0_Depart表匹配,您只关心\'mod \'和2值吗?
如果您只关心那些与\ _mod \'和2个条件专门与0_depart相关的人员,那么我将首先从THIS表开始反向查询,然后再加入其余的查询。
通过关系或条件在表上拥有键始终可以提高性能(相对于没有索引)。
以最小的FIRST集开始查询,然后加入其他表。
通过澄清您的问题...我将从最内层开始...它是谁,以及他们与哪个部门关联...然后从那里得到主持人(来自有条件的部门)...然后获得实际的主持人\的名称信息...最终根据MODERATOR的部门进入您的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
请注意,我如何对查询进行分层以获取每个部分,并加入下一个,下一个和下一个。我正在基于前一个结果构建链,并使用清晰的“别名”引用来澄清内容。现在,您可以通过它们各自不同的“别名”引用从任何级别中获取各个元素。
, EXPLAIN的输出向我们显示,列出的第一张和第三张表(a&d)没有数据库引擎在执行此查询时使用的任何索引。两者的键列均为NULL-这很可惜,因为它们都是\'large \'表(好的,它们并不是很大,但与其余表相比,它们却是大\'uns) 。
从查询的角度来看,在0_activite
上的user
上的索引和在0_depart
上的(depart,rank,user_sec)
上的索引将在某种程度上提高性能。
, 您会看到列key
和key_len
为空,这意味着它未使用possible_keys
列中的任何键。因此表a
和d
都在扫描所有行。 (在“行”列中检查较大的数字。您希望此数字较小)。
处理0_depart
:
确保您有一个键(d.depart,d.rank,d.user_sec
),它是0_depart联接的一部分。
处理0_activite
:
我不是肯定的,但也应为GROUP
列建立索引,因此您需要在a.user
上输入键
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。