[英]Sub-query Optimization Talk with an example case
我需要建议,并希望分享我在查询优化方面的经验。 本周,我发现自己陷入了一个有趣的困境。 我是mySql的新手(理论为2年,实践经验不足)
环境 :
我有一个表,其中包含带有“类型”列的文章,另一个表article_version包含在数据库中添加文章的日期,还有一个表,其中包含所有文章类型以及类型标签和填充物。
前两张桌子非常大(800000多个字段,并且每天都在增长),第三张桌子自然很小。 article表中有很多列,但是我们只需要文章中的“ ID”和“ type”以及article_version中的“ dateAdded”就可以简化事情。
我想做的事 :
对于指定的“ dateAdded”,该查询返回每种类型的文章数(有约50种要扫描的类型)。 已经存在的是50个独立的计数,每种文档类型为oO(效率不高,很长(通常〜5秒))。
我想在一个查询中完成所有操作,然后想到了:
SELECT type,
(SELECT COUNT(DISTINCT articles.ID)
FROM articles
INNER JOIN article_version
ON article_version.ARTI_ID = legi_arti.ID
WHERE type = td.NEW_ID
AND dateAdded = '2009-01-01 00:00:00') AS nbrArti
FROM type_document td
WHERE td.NEW_ID != ''
GROUP BY td.NEW_ID;
外部选择(type_document)允许我获取所需的55种文档类型。 子查询正在计算给定日期'2009-01-01'中每个type_document的文章。
常见的结果是:
* type * nbrArti * ************************* * 123456 * 23 * * 789456 * 5 * * 16578 * 98 * * .... * .... * * .... * .... * *************************
该查询完成了工作,但是子查询中的联接使此过程非常缓慢,如果我是对的,原因是服务器为每种类型进行了联接,因此该解决方案超过了50次比每种类型分别进行50个查询要慢得多,真棒:/
一个解法
我自己想出了一个解决方案,可以以相同的结果极大地提高性能,我只是创建了一个与subQuery相对应的视图,对每种类型的id进行了连接……而且Boom很快
我认为,如果我错了,请纠正我,原因是服务器仅运行一次JOIN语句。
该解决方案比现有解决方案快约5倍,比我的第一次尝试快约20倍。 甜
问题/想法
抱歉,我不是英语,这不是我的主要语言。
您不能在(type, date_added)
上创建单个索引,因为这些字段位于不同的表中。
如果没有该视图,则子查询很可能会选择article
作为主导表,并且选择type
的索引不是很严格。
通过创建视图,您可以强制子查询首先计算所有类型的总和(使用date
上的选择性索引),然后使用JOIN BUFFER
(仅对55
种类型足够快)。
您可以通过如下重写查询来获得类似的结果:
SELECT new_id, COALESCE(cnt, 0) AS cnt
FROM type_document td
LEFT JOIN
(
SELECT type, COUNT(DISTINCT article_id) AS cnt
FROM article_versions av
JOIN articles a
ON a.id = av.article_id
WHERE av.date = '2009-01-01 00:00:00'
GROUP BY
type
) q
ON q.type = td.new_id
不幸的是, MySQL
无法执行表假脱机或哈希联接,因此要提高性能,您需要对表进行非规范化:将type
添加到article_version
并在(date, type)
上创建一个复合索引。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.