2011-10-07 73 views
3

我有几个表,我结合在一起时,我执行以下查询:MySQL的性能下降联接查询

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的。我从我的本地机器运行这是相当低规格(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 
+0

你对'authors.last_name'的指数?你有用于连接的列的索引吗?你有'authors.last_name'上的索引吗?如果你根本没有索引,随着表的增长,它会变得越来越慢。 –

+0

发布yout表结构。 (我的意思是'authors.last_name'和'article.year'。) –

+0

不,目前我没有任何索引在查询中使用的列,好点。我没有添加它们,因为在这个阶段它看起来像是一个相当小的表格,但我会尝试在受影响的列上添加索引,并查看它是否可以解决任何问题...... – DrNoFruit

回答

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

正如@Tudor所提到的,你需要一个'article.author_id'字段,它将成为'author(id)'的'FOREIGN KEY'。您还需要声明哪个字段是'PRIMARY KEY'(在这两个表中),并且还有在'WHERE'或'ON'中使用的更多字段的索引。 –

+0

谢谢你们,我会玩一玩,让你知道结果。 – DrNoFruit

+1

只是为了让大家都知道我在相关的列上添加了索引,并且它产生了巨大的差异,所以非常感谢。感觉有点愚蠢,因为没有做到这一点,我只是没想到它在如此小的桌子上如此重要。 – DrNoFruit

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/

+0

你为什么认为这种改变会有所帮助? –

+0

你的链接的例子只有一个表 - “GROUP BY” - 在子查询中,在外部查询中有'JOIN'。你有它倒过来。 –