0

我很难理解我是否正确地索引了这个查询,它有点慢,我觉得它可以使用优化。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 表(删除了无关的 deta,大小约为 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;

用户表(删除了不相关的 deta,大小约为 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
4

2 回答 2

0

我建议将用户 ID 索引(假设您现在没有使用它)更改为active先有userid后有。

这应该使它对这个查询更有用。

于 2013-08-20T22:18:14.447 回答
0

Using filesort可能是你的性能杀手。

您需要来自用户快照的记录,其中 active = 'N' 并且需要按 ins_time 排序。

ALTER TABLE usersnaps ADD KEY active_ins_time (active,ins_time);

索引按排序顺序存储,并按排序顺序读取...因此,如果优化器选择该索引,它将使用 active = 'N' 的记录,并且——嘿,看看——它们已经排序通过 ins_time - 因为那个索引。因此,当它读取索引引用的行时,内部的结果集已经按照您想要的顺序排列ORDER BY,优化器应该意识到这一点……不需要文件排序。

于 2013-08-21T02:49:16.803 回答