子查询优化与示例案例对话

时间:2009-11-25 11:04:36

标签: optimization mysql count query-optimization

我需要建议,并希望分享我的查询优化经验。本周,我发现自己陷入了一个有趣的困境。 我是mySql的新手(2年理论,不到一个实用)

环境:

我有一个表包含一个列'type'的文章,另一个表article_version包含一个在DB中添加一篇文章的日期,另一个表包含所有文章类型以及类型标签和东西...

2张第一张桌子很大(800000+场并且每天都在增长),第3张桌子自然是小型的。文章表有很多专栏,但我们只需要文章中的'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,它是f.a.s.t。

我想,如果我错了,请纠正我,原因是服务器只运行一次JOIN语句。

此解决方案比已经存在的解决方案快约5倍,比第一次尝试快约20倍。甜

问题/想法

  • 还有另一种观点,我现在需要检查一下文件插入后我是否放弃了胜利...
  • 有没有办法通过从子查询中获取JOIN语句来改进原始查询? (并且摆脱了观点)
  • 任何其他提示/想法? (例如,在服务器优化中......)

为我的近似英语道歉,这不是我的主要语言。

1 个答案:

答案 0 :(得分:1)

您无法在(type, date_added)上创建单个索引,因为这些字段位于不同的表中。

如果没有视图,子查询最有可能选择article作为前导表,而type上的索引选择性不强。

通过创建视图,您可以强制子查询首先计算所有类型的总和(使用date上的选择性索引),然后使用JOIN BUFFER(仅适用于{{}} {1}}类型)。

您可以通过重写查询来实现类似的结果:

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上的综合索引。