mysql在带有联接查询的小表上的性能较慢

mysql在带有联接查询的小表上的性能较慢,mysql,performance,left-join,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秒的时间,考虑到需要处理的行数相对较少,返

在执行以下查询时,我将两个表连接在一起:

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秒的时间,考虑到需要处理的行数相对较少,返回结果的速度似乎慢得令人难以置信。我做错什么了吗

如果对查询运行解释,我会得到以下结果:

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。我是从我的本地机器上运行的,它的规格相当低(WindowsXP,1GHz,1gb内存),但即便如此,我还是认为这样会更快。如果我将更多的行加载到表中,它开始需要几分钟而不是几秒钟

有什么想法吗

下表结构:

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

尝试在列
authors.last_name
authors.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
上建立一个索引,尽管不是为了这个查询,而是作为一个一般的最佳实践,正如都铎所说,添加索引。您还可以按提取组

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
执行此操作时,首先通过联接获取,然后在集合中应用聚合函数

解释
,看看改进的地方在哪里

建议的字体:


你有关于作者姓氏的索引吗?在用于联接的列上有索引吗?你有关于作者姓氏的索引吗?如果您根本没有索引,那么随着表的大小的增长,索引速度会越来越慢。(我的意思是
作者。姓氏
文章。年份
)不,目前我没有查询中使用的列的任何索引,很好。在这个阶段,我没有添加它们,因为它看起来像是一个相当小的表,但是我会尝试在受影响的列中添加索引,看看它是否解决了什么……你还应该考虑制作<代码>年份 <代码> int >代码>,而不是<代码> char(20)< /C>。它是4个字节(如果将其设置为
SMALLINT
,则为2个字节),而不是20个字节。空间越小,索引的空间越小,没有人可以添加一行
year='my gosh,2012'
。正如@Tudor提到的,你需要一篇
文章。author\u id
字段将是
外键
author(id)
。您还需要声明哪个字段是
主键
(在两个表中),并对
WHERE
on
中使用的任何其他字段进行进一步的索引。谢谢各位,我将播放一部剧,让你们知道结果。只是为了让大家知道,我在相关列上添加了索引,这带来了巨大的差异,所以谢谢你。一开始没有做这件事让我觉得有点傻,我只是没想到它在这么小的表上会如此重要。为什么你认为这个更改会有帮助呢?you link的示例只有一个表-子查询中的
GROUP BY
,外部查询中的
JOIN
。你把它倒过来了。