查询优化

时间:2011-01-15 10:47:33

标签: mysql sql query-optimization

SELECT nar.name, nar.reg, stat.lvl
FROM members AS nar
JOIN stats AS stat 
ON stat.id = nar.id
WHERE nar.ref = 9

我在两个表中都有id的索引,我也有索引referavo。但是,它仍会检查stats表中的所有行(我使用Explain来获取此信息),但是在members表中,它只检查一行应该如何。统计表有什么问题?非常感谢你。

CREATE TABLE `members` (
 `id` int(11) NOT NULL
 `ref` int(11) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT


CREATE TABLE `stats` (
 `id` int(11) NOT NULL AUTO_INCREMENT
 PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC



id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE stat ALL PRIMARY NULL NULL NULL 22  
1 SIMPLE nar eq_ref PRIMARY PRIMARY 4 table_nme.stat.id 1 Using where

2 个答案:

答案 0 :(得分:4)

你的桌子非常小 - 只有23行很小

MySQL会根据表中的行数以及根据统计数据选择的估计数来选择不同的查询计划。您应该使用实际数据对性能进行性能测试 - 数据量和数据中值的分布应尽可能真实。否则,MySQL在测试中选择的查询计划可能与您的实时系统的实际查询计划不同。

你的表太小了,使用索引可能而不是直接检查表。请记住,检查已经在内存中的数据很快,但读取速度很慢。访问索引可能需要额外读取 - 首先必须获取索引并读取以查找要选择的行,然后如果索引不是覆盖索引,则必须获取表中的相关行并读取以获取不在索引中的值。 MySQL完全有权不使用索引,即使它有可用,如果它认为这样做会导致计划速度变慢。

在表格中添加更多行(数千个),然后再次尝试运行EXPLAIN。您可能会发现,当您有更多行时,PRIMARY KEY索引将用于连接。

答案 1 :(得分:1)

MySQL每个表一次只能使用一个索引,因此它使用索引查看member行,然后执行ID的顺序搜索。

您必须为members

创建多列索引
 CREATE INDEX idref ON members(id,ref);

如果没有变好,请尝试反向(首先:在成员上删除索引idref)

 CREATE INDEX idref ON members(ref,id);

(我现在不能自己尝试)