优化MySQL查询以实现group_concat函数
上面的查询大约需要800毫秒到1000毫秒才能运行 如果我附加一个优化MySQL查询以实现group_concat函数,mysql,sql,innodb,myisam,Mysql,Sql,Innodb,Myisam,上面的查询大约需要800毫秒到1000毫秒才能运行 如果我附加一个group\u concat语句,则查询需要8-10秒: SELECT SQL_NO_CACHE link.stop, stop.common_name, locality.name, stop.bearing, stop.latitude, stop.longitude FROM service JOIN pattern ON pattern.service = service.code JOIN link ON link.se
group\u concat
语句,则查询需要8-10秒:
SELECT SQL_NO_CACHE link.stop, stop.common_name, locality.name, stop.bearing, stop.latitude, stop.longitude
FROM service
JOIN pattern ON pattern.service = service.code
JOIN link ON link.section = pattern.section
JOIN naptan.stop ON stop.atco_code = link.stop
JOIN naptan.locality ON locality.code = stop.nptg_locality_ref
GROUP BY link.stop
如何使用group\u concat
语句更改此查询,使其在2秒内运行
SQL Fiddle:
解释这两个查询的语句:备注:您正在使用。它恰好对您起作用,因为link.stop
与stop.atco_code
相连,后者本身就是主键。但是你需要非常小心
我建议您添加一些复合索引。您可以在服务
上加入模式
,并根据部分
加入。所以加上这个索引
SELECT SQL_NO_CACHE link.stop, link.stop, stop.common_name, locality.name, stop.bearing, stop.latitude, stop.longitude, group_concat(service.line) lines
这将使查询只使用索引,而不必点击表本身来检索联接或GROUP\u CONCAT()操作所需的信息。(您也可以仅删除服务
上的索引,此新索引使其成为冗余索引)
类似地,您希望在链接
表上创建一个索引(section,stop)
,并在部分
上删除索引
在stop
上,您正在使用大多数列,并且在atco_code
上已经有了索引(PK),所以就让这一个吧
最后,在locality
上,在(code,name)
上放置一个索引
所有这些索引猴子业务都应该减少MySQL为满足您的查询所必须做的工作
现在看,只要将WHERE anywhere=anywhere
添加到查询中,就可能需要将一列添加到一个或多个索引中。你一定要好好读一读;良好的索引是您的数据类型成功的关键因素
插入大量行后,还应在每个表上运行ANALYZE TABLE xxxx
,以确保查询优化器可以看到有关表和索引内容的适当信息。备注:您正在使用。它恰好对您起作用,因为link.stop
与stop.atco_code
相连,后者本身就是主键。但是你需要非常小心
我建议您添加一些复合索引。您可以在服务
上加入模式
,并根据部分
加入。所以加上这个索引
SELECT SQL_NO_CACHE link.stop, link.stop, stop.common_name, locality.name, stop.bearing, stop.latitude, stop.longitude, group_concat(service.line) lines
这将使查询只使用索引,而不必点击表本身来检索联接或GROUP\u CONCAT()操作所需的信息。(您也可以仅删除服务
上的索引,此新索引使其成为冗余索引)
类似地,您希望在链接
表上创建一个索引(section,stop)
,并在部分
上删除索引
在stop
上,您正在使用大多数列,并且在atco_code
上已经有了索引(PK),所以就让这一个吧
最后,在locality
上,在(code,name)
上放置一个索引
所有这些索引猴子业务都应该减少MySQL为满足您的查询所必须做的工作
现在看,只要将WHERE anywhere=anywhere
添加到查询中,就可能需要将一列添加到一个或多个索引中。你一定要好好读一读;良好的索引是您的数据类型成功的关键因素
插入大量行后,还应在每个表上运行ANALYZE TABLE xxxx
,以确保查询优化器可以看到有关表和索引内容的适当信息。此查询需要多长时间
ALTER TABLE pattern ADD INDEX service_section (service, section, line);
我认为您可以在子查询中执行group\u concat()
,因此外部查询不需要聚合。当子查询中有一个表时,这可以加快查询速度。在你的情况下,有两个
最终结果可能是:
link.section=pattern.section
SELECT p.section, GROUP_CONCAT(s.line)
FROM pattern p join
service s
ON p.service = s.code
GROUP BY p.section
对于此查询,您需要以下附加索引:pattern(section,service)
和service(code,line)
我不知道这是否有效,但值得一试
注意:这是假设您真的不需要对其余列使用分组依据。此查询需要多长时间
ALTER TABLE pattern ADD INDEX service_section (service, section, line);
我认为您可以在子查询中执行group\u concat()
,因此外部查询不需要聚合。当子查询中有一个表时,这可以加快查询速度。在你的情况下,有两个
最终结果可能是:
link.section=pattern.section
SELECT p.section, GROUP_CONCAT(s.line)
FROM pattern p join
service s
ON p.service = s.code
GROUP BY p.section
对于此查询,您需要以下附加索引:pattern(section,service)
和service(code,line)
我不知道这是否有效,但值得一试
注意:这是假设您真的不需要对其余列使用分组依据。您能为该查询发布解释的结果吗?(我注意到你的一个表在MyISAM中,有一个地理空间索引。)你可能想读一下:@OllieJones嗨,Ollie,我在问题中添加了一个解释,抱歉没有在我脑海中提到MyISAM表,并且是一个粗略的近似值,在SQL中,哪一个GROUP_CONCAT是解决方案是没有问题的。当您优化GROUP BY查询时,结果集的所有列都是相关的。这是因为复合索引可以产生很大的性能差异。@OllieJones基于这些信息,我已经确定所有选定的字段现在都在查询中。您可以为这个查询发布EXPLAIN
的结果吗?(我注意到您的一个表在MyISAM中,并且有一个地理空间索引。)您可能想阅读以下内容:@OllieJones嗨Ollie,我在问题中添加了一个EXPLAIN
,抱歉没有提到M