Mysql 通过在特定表上添加联接来执行非常慢的SQL查询
首先,我不确定我是否应该把我的问题贴在这里 我有一个简单的多连接SQL查询Mysql 通过在特定表上添加联接来执行非常慢的SQL查询,mysql,sql,Mysql,Sql,首先,我不确定我是否应该把我的问题贴在这里 我有一个简单的多连接SQL查询 SELECT ho.id_host AS "ID", ho.Hostname AS "Nom", CONCAT(COUNT(DISTINCT ip.id_ip), " IP") AS "IP", GROUP_CONCAT(ip.IP_Address SEPARATOR ", ") AS "IPList", ho.OS, ho.Version AS "Version OS",
SELECT
ho.id_host AS "ID",
ho.Hostname AS "Nom",
CONCAT(COUNT(DISTINCT ip.id_ip), " IP") AS "IP",
GROUP_CONCAT(ip.IP_Address SEPARATOR ", ") AS "IPList",
ho.OS,
ho.Version AS "Version OS",
CONCAT(COUNT(DISTINCT us.id_user), " utilisateur(s)") AS "Utilisateurs",
GROUP_CONCAT(us.Nom_user SEPARATOR ", ") AS "UtilisateursList",
CONCAT(COUNT(DISTINCT co.id_composant), " composant(s)") AS "Composants",
GROUP_CONCAT(co.Nom_composant SEPARATOR ", ") AS "ComposantsList"
FROM
Host ho
LEFT OUTER JOIN
IP ip ON ho.id_host = ip.id_host
LEFT OUTER JOIN
User us ON ho.id_host = us.id_host
LEFT OUTER JOIN
Composant co ON us.id_user = co.id_user
GROUP BY
ho.id_host;
完成此查询需要0.250~0.300秒。如果添加所需的最后一个连接,则完成查询需要9~12秒。我不知道为什么
LEFT OUTER JOIN
Informations inf ON ho.id_host = inf.id_host
最后一个表是数据库中最小的表之一,只有172行。JOIN的ON子句比较两个int而不是两个varchar。如果删除除此之外的所有连接,查询只需0072秒即可完成
我想知道,为什么在将联接添加到最小的表之一时,查询还要花费10秒才能完成。此外,我有一些查询,在较大的表上有更多的连接,它们运行得更快
编辑:解释
给出以下信息:
+----+-------------+-------+------+---------------+---------+---------+-----------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+---------+---------+-----------------+------+---------------------------------+
| 1 | SIMPLE | ho | ALL | NULL | NULL | NULL | NULL | 352 | Using temporary; Using filesort |
| 1 | SIMPLE | ip | ref | id_host | id_host | 5 | cmdb.ho.id_host | 11 | |
| 1 | SIMPLE | us | ref | id_host | id_host | 5 | cmdb.ho.id_host | 32 | |
| 1 | SIMPLE | co | ref | id_user | id_user | 5 | cmdb.us.id_user | 11 | |
| 1 | SIMPLE | inf | ALL | NULL | NULL | NULL | NULL | 172 | |
+----+-------------+-------+------+---------------+---------+---------+-----------------+------+---------------------------------+
你可以看看执行计划。但根据您的描述,您可能需要在表上创建索引:
create table idx_composant_id_user on composant(id_user)
对于那些有同样问题的人,@Madhur Bhaiya和@Gordon Linoff帮助我将时间从10秒减少到0,4秒 我添加了按NULL排序的
(-2s),并在信息(id\u主机)
(-7,6s)上创建了一个索引。最后一个SQL查询如下所示:
SELECT
ho.id_host AS "ID",
ho.Hostname AS "Nom",
CONCAT(COUNT(DISTINCT ip.id_ip), " IP") AS "IP",
GROUP_CONCAT(ip.IP_Address SEPARATOR ", ") AS "IPList",
ho.OS,
ho.Version AS "Version OS",
CONCAT(COUNT(DISTINCT us.id_user), " utilisateur(s)") AS "Utilisateurs",
GROUP_CONCAT(us.Nom_user SEPARATOR ", ") AS "UtilisateursList",
CONCAT(COUNT(DISTINCT co.id_composant), " composant(s)") AS "Composants",
GROUP_CONCAT(co.Nom_composant SEPARATOR ", ") AS "ComposantsList",
inf.Jumelle,
inf.Baie
FROM
Host ho
LEFT OUTER JOIN
IP ip ON ho.id_host = ip.id_host
LEFT OUTER JOIN
User us ON ho.id_host = us.id_host
LEFT OUTER JOIN
Composant co ON us.id_user = co.id_user
LEFT OUTER JOIN
Informations inf ON ho.id_host = inf.id_host
GROUP BY
ho.id_host
ORDER BY
NULL;
请仔细阅读,因为您的查询使用GROUP BY的方式通常不是RDMS中使用GROUP BY的方式。。。您信任一种称为函数依赖性的功能,该功能只能在MySQL 5.7.5+上使用,并且当sql_mode only_FULL_GROUP_BY处于活动状态时(强制MySQL引擎按照ANSI/ISO sql 1999+标准规则重新分级GROUP BY)才能获得正确的数据,否则您可能会面临无效(不相关)的风险数据..查询性能相关问题总是需要查询的EXPLAIN..
计划的结果。如果您的MySQL版本允许,请在问题中提供EXPLAIN format=JSON…
的结果;如果没有,您只需运行EXPLAIN..
请定义两个索引(如果尚未定义):Host(id\u Host)
和Informations(id\u Host)
。另外,在groupby..
的末尾,指定orderbynull
以避免文件排序(这是旧版本MySQL中的一个限制,MySQL 8中已经修复了这一限制)+orderbynull
将时间减少约2秒,创建索引将总时间减少到约0.4秒。谢谢你的帮助!我认为你是对的。当我查看执行计划时,信息的类型是ALL
。