mysql在连接查询的小表上性能较差

时间:2011-10-07 08:29:49

标签: mysql performance left-join

当我执行以下查询时,我有几个表连接在一起:

SELECT article.year, authors.last_name, count(DISTINCT article.id) as count FROM
article LEFT JOIN authors ON article.id = authors.id WHERE authors.last_name =
'bloggs' GROUP BY article.year

出于某种原因,这需要6到7秒的时间来返回结果,这对我来说似乎要慢得多,因为它必须处理的行数相对较少。我在这里做错了吗?

如果我在查询上运行EXPLAIN,我会得到以下内容:

select_type    table    type   possible_keys  key    key_len    ref    rows    extra
=====================================================================================
simple         article  all    null           null    null      null   762     using temporary; using filesort
simple         authors  all    null           null    null      null   5061    using where; using join buffer

这两个表都是InnoDB。我从我的本地机器运行这个相当低的规格(windows xp,1 ghz,1gb ram),但即便如此,我还以为这会更快。如果我在表中加载更多行,则开始需要几分钟而不是几秒钟。

有什么想法吗?

下面的表结构:

Article:

field    type       null    key    default    extra
=======================================================
id       int        yes            null
year     char(20)   yes            null
volume   char(20)   yes            null
issue    char(20)   yes            null
title    text       yes            null

Authors:

field      type       null    key    default    extra
=======================================================
id         int        yes            null
last_name  char(100)  yes            null
initials   char(10)   yes            null

2 个答案:

答案 0 :(得分:2)

尝试在列authors.last_nameauthors.id上添加索引。

但是,你确定你的查询没问题吗?不应该看起来像:

SELECT article.year, authors.last_name, count(DISTINCT article.id) as count FROM
article LEFT JOIN authors ON article.author_id = authors.id WHERE authors.last_name =
'bloggs' GROUP BY article.year

如果是这样,则需要articles.author_id上的索引 - 尽管不是针对此查询,而是作为一般的最佳做法

答案 1 :(得分:0)

正如都铎所说,添加索引。您也可以通过提取分组。

SELECT * FROM (SELECT article.year, authors.last_name, count(DISTINCT article.id) as count FROM
article LEFT JOIN authors ON article.author_id = authors.id WHERE authors.last_name =
'bloggs') GROUP BY article.year

执行此操作首先通过连接提取,然后在集合中应用聚合函数。

explain了解改善的位置。

建议字体:

http://kccoder.com/mysql/join-group-by-performance/