使用临时;使用filesort ..慢查询

时间:2011-06-18 18:27:39

标签: mysql optimization

我有一个非常简单的查询,我试图优化,它需要2~5秒才能执行。

这是我的CREATE TABLE

CREATE TABLE `artist` (
  `id` INTEGER NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(100) character set utf8 NOT NULL,
  `bio` MEDIUMTEXT character set utf8 DEFAULT NULL,
  `hits` INTEGER NOT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE `album` (
  `id` INTEGER NOT NULL AUTO_INCREMENT,
  `artist_id` INTEGER NOT NULL,
  `title` VARCHAR(100) character set utf8 NOT NULL,
  `year` INTEGER,
  `hits` INTEGER NOT NULL,
  PRIMARY KEY (`id`),
KEY (`artist_id`)
);

CREATE TABLE `track` (
  `id` INTEGER NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(100) character set utf8 NOT NULL,
  `lyric` MEDIUMTEXT character set utf8,
  `album_id` INTEGER NOT NULL,
  `hits` INTEGER NOT NULL,
  `date` datetime NOT NULL,
  PRIMARY KEY (`id`),
KEY (`album_id`)
);

ALTER TABLE `album` ADD FOREIGN KEY (artist_id) REFERENCES `artist` (`id`);
ALTER TABLE `track` ADD FOREIGN KEY (album_id) REFERENCES `album` (`id`);

这是我正在运行的查询

SELECT DISTINCT artist.name, track.name
FROM track
LEFT JOIN album ON track.album_id = album.id
LEFT JOIN artist ON album.artist_id = artist.id
ORDER BY track.hits DESC
LIMIT 5 

解释选择显示:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  track   ALL     NULL    NULL    NULL    NULL    103796  Using temporary; Using filesort
1   SIMPLE  album   eq_ref  PRIMARY     PRIMARY     4   lyrics.track.album_id   1    
1   SIMPLE  artist  eq_ref  PRIMARY     PRIMARY     4   lyrics.album.artist_id  1    

我是MySQL的新手,但我想使用Using temporary;使用filesort是不好的,这就是为什么查询非常慢,你们可以在这里提示我吗?谢谢!

更新:这里的主要问题是,在具有不同ID的数据库中,同一首歌可以是5次,因为同一首歌可以在不同的专辑中。如果我不使用不同的,这不会发生,因为这个原因我必须

4 个答案:

答案 0 :(得分:1)

您可以通过添加

来使用索引
create index idx_tracks_on_album_id_name_hits on track(album_id, name, hits);

由于您在两个表中执行DISTINCT,因此没有索引可能找到唯一的行,因此它将它放入临时表中以删除重复项。

答案 1 :(得分:0)

我认为如果你在trackhits上创建索引,你可能会摆脱“使用临时;使用filesort”,其原因可能是因为MySQL无法找到要执行的索引那种。

ALTER TABLE `track`
ADD KEY `idx_hits` (`hits`);

让我知道它是否有效。

答案 2 :(得分:0)

为什么要使用DISTINCT?为什么使用LEFT JOIN(而不是JOIN)?

答案 3 :(得分:0)

此答案不是原始问题的100%答案。最初的问题是使用我的问题中的消息进行搜索时会出现什么情况,因此,以防万一它对其他人有帮助,我将为密切相关的问题保留解决方案。

“正在使用临时文件;正在使用文件排序” 实际上是一个红色鲱鱼,添加的索引从未被使用过。未使用索引,因为其中一个联接表的字符编码与另一个不同。

转换查询中的所有表,以便它们都使用相同的字符编码立即对其进行修复。

(在我们的示例中,将utf8编码的表转换为latin1编码)

希望它可以帮助某人。