坚持在MySql上进行优化,在EXPLAIN上使用临时的,使用文件排序...消息

时间:2010-11-18 16:08:27

标签: mysql optimization

我正在分析一个Web应用程序,试图减少不必要的查询延迟,我发现一个似乎很简单,但需要花费大量时间执行。

使用EXPLAIN我收到以下消息:

Using where; Using temporary; Using filesort

这是查询:

SELECT `bt`.`id_brand`
FROM `brands_translation` AS `bt`
WHERE bt.code_language = 'es'
GROUP BY `bt`.`id_brand`
ORDER BY `bt`.`name` ASC

表格定义:

CREATE TABLE IF NOT EXISTS `brands_translation` (
  `id_brand` int(64) unsigned NOT NULL,
  `code_language` varchar(3) NOT NULL,
  `name` varchar(128) NOT NULL,
  `link` varchar(255) default NULL,
  `logo` varchar(255) default NULL,
  `description` text NOT NULL,
  KEY `id_brand` (`id_brand`),
  KEY `code_language` (`code_language`),
  KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我尝试解决它为每个涉及的字段创建索引而没有结果。

有什么想法吗?

提前致谢

2 个答案:

答案 0 :(得分:0)

使用正确的INDEX,MySQL可以在没有ORDER BY语句的情况下正确地对结果进行排序。您需要查看ORDER BY OptimizationLIMIT Optimization

否则,临时和文件排序的使用来自不同的GROUP BY和ORDER BY。对于这个特定的查询,我会删除你现有的索引并添加这个:

ALTER TABLE  `brands_translation` ADD INDEX (`code_language` , `id_brand` , `name` );

当然,这可能会影响整个项目中的其他查询。完成后,将查询更改为:

SELECT `bt`.`id_brand`
FROM `brands_translation` AS `bt`
WHERE bt.code_language = 'es'
GROUP BY `bt`.`id_brand`, `bt`.`name`
ORDER BY `bt`.`id_brand`, `bt`.`name`

意识到您可能不想按名称分组,可以从GROUP BY语句中删除名称,但这会再次为您using temporary(因为GROUP和ORDER不同)。

答案 1 :(得分:0)

请看以下......

drop table if exists brands_translation;
create table brands_translation
(
code_language varchar(3) not null,
id_brand int unsigned not null,
-- other fields here...
primary key(code_language, id_brand) -- clustered composite primary key (please !!)
) 
engine=innodb;

为什么引用`当你不需要并整理你的数据类型时。