了解当文本列很多时,为什么按查询分组会减慢速度

时间:2019-04-07 15:34:47

标签: mysql

我有一个运行缓慢的查询,我想出了一个更快的选择,但我希望获得一些帮助,以了解为什么原始查询这么慢。

我的问题的简化版使用两个表。第一个表的简化版本称为配置文件,

`profiles` (
 `id` int(11),
 `title` char(255),
 `body` text,
 `pin` int(11),
  PRIMARY KEY (`id`),
  UNIQUE KEY `pin` (`pin`)
 )

我的第二张桌子的简化版电话是

`calls` (
 `id` int(11),
 `pin` int(11),
 `duration` int(11),
 PRIMARY KEY (`id`),
 KEY `ivr_id` (`pin`)
)

我的查询应该获得完整的配置文件,并加上配置文件收到的呼叫数量。我正在使用的查询是

SELECT profiles.*, COUNT(*) AS num_calls 
FROM profiles 
LEFT JOIN calls 
ON profiles.pin = calls.pin
GROUP BY profiles.pin

使用大约100个配置文件和大约250,000个呼叫,此查询大约需要10秒钟,这很慢。

如果我修改查询以仅从配置文件而不是所有列中选择标题,则查询会更快。如果我修改查询以删除分组依据,其速度也快得多。如果我只是从个人资料表中选择所有内容,那么它也是一个快速查询。

我的实际配置文件表还有更多的文本和字符字段。选择的文本字段越多,查询速度越差。当文本字段不包含在JOIN或GROUP中时,为什么这些文本字段会导致查询如此缓慢?

我想出了一个稍有不同的查询,该查询要快得多,不到半秒钟。该查询是:

SELECT profiles.*, temp.readings 
FROM profiles 
LEFT JOIN (
    SELECT pin ,COUNT(*) AS readings 
    FROM calls 
    GROUP BY pin
) AS temp 
ON temp.pin=profiles.pin

虽然我认为我已经解决了速度问题,但是我想了解在第一次查询中是什么导致了问题。

=========更新=======

我刚刚配置了两个查询,并且整个速度差异都在“发送数据”部分中。慢查询大约10秒,快查询大约0.1秒

=========更新2 ========

与@scaisEdge讨论之后,我想我可以改写我的问题。考虑一个表T1,它具有〜40列,其中8个是TEXT类型,并且具有〜100行,而表T2具有5列的INT和VARCHAR类型,具有〜250,000行。为什么会这样:

SELECT T1.* FROM T1 is fast

SELECT T1.* FROM T1 JOIN T2 GROUP BY T1.joinfield is slow
如果selectfield是INT或VARCHAR,则

SELECT T1.selectfield FROM T1 JOIN T2 GROUP BY T1.joinfield很快

1 个答案:

答案 0 :(得分:0)

这应该是因为

第一个查询将100个配置文件与250,000个调用连接起来,然后按result减少返回的行分组。而选择配置文件。*表示对每个匹配行都具有对配置文件表数据的完全访问权限

然后第二个查询将100个配置文件与TEMP的子查询返回的行数(可能少于250,000)相结合,从而减少了对表配置文件数据的访问次数

而不是个人资料。*尝试仅访问引脚列

SELECT profiles.pin, COUNT(*) AS num_calls 
FROM profiles 
LEFT JOIN calls ON profiles.pin = calls.pin
GROUP BY profiles.pin

作为建议,您应该注意,仅在5.7版之前的MySQL版本才允许对第一个查询使用group by,因为在select子句中使用不带column列的group by列,并且不受聚合函数的影响并且在DEFALT中不允许在GROUP BY中提及并产生错误..