查找此MySQL查询的最佳索引

时间:2013-08-20 21:53:37

标签: mysql

我很难理解我是否正确地索引了这个查询,它有点慢,我觉得它可以使用优化。 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

2 个答案:

答案 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,优化器应该实现这一点......不需要文件输出。