繁体   English   中英

子查询优化实例案例

[英]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倍。

问题/想法

  • 从另一个角度来看,现在我需要检查插入文档时是否没有失去胜利的余地...
  • 是否可以通过从子查询中删除JOIN语句来改进原始查询? (摆脱视图)
  • 还有其他提示/想法吗? (例如,在服务器优化中...)

抱歉,我不是英语,这不是我的主要语言。

您不能在(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM