我正在分析一个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;
我尝试解决它为每个涉及的字段创建索引而没有结果。
有什么想法吗?
提前致谢
答案 0 :(得分:0)
使用正确的INDEX
,MySQL可以在没有ORDER BY
语句的情况下正确地对结果进行排序。您需要查看ORDER BY Optimization和LIMIT 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;
为什么引用`当你不需要并整理你的数据类型时。