Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 通过在特定表上添加联接来执行非常慢的SQL查询_Mysql_Sql - Fatal编程技术网

Mysql 通过在特定表上添加联接来执行非常慢的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",

首先,我不确定我是否应该把我的问题贴在这里

我有一个简单的多连接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"
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