简体   繁体   English

为该MySQL查询找到最佳索引

[英]Finding optimal indexes for this MySQL query

I'm struggling to understand if I've indexed this query properly, it's somewhat slow and I feel it could use optimization. 我正在努力理解是否正确索引了该查询,它有点慢,我觉得它可以使用优化。 MySQL 5.1.70 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 table (irrelevant deta removed, size about 250k records) : 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;

user table (irrelevant deta removed, size about 300k records) : 用户表(不相关的deta已删除,大小约为30万条记录):

 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 table (size about : 60k records) : 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;

Explain extended returns : 解释扩展收益:

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

I would recommend changing the userid index (assuming you're not using it right now) to have active first and userid later. 我建议更改userid索引(假设您现在不使用它),使其先active然后再具有userid

That should make it more useful for this query. 这应该使其对于此查询更加有用。

Using filesort is probably your performance killer. Using filesort可能是您的性能杀手。

You need the records from usersnaps where active = 'N' and you need them sorted by ins_time. 您需要来自usersnaps的记录,其中active ='N',并且需要按ins_time对其进行排序。

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

Indexes are stored in sorted order, and read in sorted order... so if the optimizer chooses that index, it will go for the records with active = 'N' and -- hey, look at that -- they're already sorted by ins_time -- because of that index. 索引按排序顺序存储,并按排序顺序读取...因此,如果优化程序选择了该索引,它将用于active ='N'的记录,并且-嘿,看一下-它们已经排序了通过ins_time-由于该索引。 So as it reads the rows referenced by the index, the result-set internally is already in the order you want it to ORDER BY , and the optimizer should realize this... no filesort required. 因此,当它读取索引所引用的行时,内部的结果集已经按照您想要ORDER BY的顺序进行了排序,优化器应该意识到这一点……不需要文件排序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM