我很难理解我是否正确地索引了这个查询,它有点慢,我觉得它可以使用优化。 MySQL 5.1.70
select snaps.id, snaps.userid, snaps.ins_time, usr.gender
from usersnaps as snaps
join user as usr on usr.id = snaps.userid
left join user_convert as conv on snaps.userid = conv.userid
where (conv.level is null or conv.level = 4) and snaps.active = 'N'
and (usr.status = "unfilled" or usr.status = "unapproved") and usr.active = 1
order by snaps.ins_time asc
usersnaps表(删除了无关的详细信息,大小约为250k记录):
CREATE TABLE IF NOT EXISTS `usersnaps` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`userid` int(11) unsigned NOT NULL DEFAULT '0',
`picture` varchar(250) NOT NULL,
`active` enum('N','Y') NOT NULL DEFAULT 'N',
`ins_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`,`userid`),
KEY `userid` (`userid`,`active`),
KEY `ins_time` (`ins_time`),
KEY `active` (`active`)
) ENGINE=InnoDB;
用户表(删除了无关的详细信息,大小约为300k记录):
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`active` tinyint(1) NOT NULL DEFAULT '1',
`status` enum('15','active','approval','suspended','unapproved','unfilled','rejected','suspended_auto','incomplete') NOT NULL DEFAULT 'approval',
PRIMARY KEY (`id`),
KEY `status` (`status`,`active`)
) ENGINE=InnoDB;
user_convert表(大小约为:60k记录):
CREATE TABLE IF NOT EXISTS `user_convert` (
`userid` int(10) unsigned NOT NULL,
`level` tinyint(4) NOT NULL,
UNIQUE KEY `userid` (`userid`),
KEY `level` (`level`)
) ENGINE=InnoDB;
解释延长回报:
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE snaps ref userid,default_pic,active active 1 const 65248 100.00 Using where; Using filesort
1 SIMPLE usr eq_ref PRIMARY,active,status PRIMARY 4 snaps.userid 1 100.00 Using where
1 SIMPLE conv eq_ref userid userid 4s snaps.userid 1 100.00 Using where
答案 0 :(得分:0)
我建议您更改用户标识索引(假设您现在不使用它),先使用active
,然后再使用userid
。
这应该使它对这个查询更有用。
答案 1 :(得分:0)
Using filesort
可能是你的表演杀手。
您需要来自usersnaps的记录,其中active ='N',您需要按ins_time排序。
ALTER TABLE usersnaps ADD KEY active_ins_time (active,ins_time);
索引按排序顺序存储,并按排序顺序读取...因此,如果优化程序选择该索引,它将用于具有active ='N'的记录,并且 - 嘿,看看它们 - 它们' re 已经按ins_time排序 - 因为该索引。因此,当它读取索引引用的行时,结果集内部已经按照您希望它的顺序ORDER BY
,优化器应该实现这一点......不需要文件输出。