mysql多列索引无法正常工作(如预期的那样)?

时间:2010-12-08 19:35:47

标签: mysql indexing sql-order-by sql-execution-plan compound-index

我有一张这样的表

CREATE TABLE IF NOT EXISTS `tbl_folder` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `owner_userid` int(11) NOT NULL,
  `name` varchar(63) NOT NULL,
  `description` text NOT NULL,
  `visibility` tinyint(4) NOT NULL DEFAULT '2',
  `num_items` int(11) NOT NULL DEFAULT '0',
  `num_subscribers` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `owner_userid` (`owner_userid`),
  KEY `vis_sub_item` (`visibility`,`num_subscribers`,`num_items`)
) ENGINE=InnoDB

因为我有一个可见性索引,num_subscribers和num_items,我希望只需要查看前15行,而EXPLAIN说55856行。任何的想法?感谢

EXPLAIN SELECT t.id, name, description, owner_userid, num_items, num_subscribers
FROM  `tbl_folder`  `t` 
WHERE visibility =2
ORDER BY  `t`.`num_subscribers` DESC ,  `t`.`num_items` DESC 
LIMIT 15

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t ref vis_sub_item vis_sub_item 1 const 55856 Using where

3 个答案:

答案 0 :(得分:2)

您的3字段索引看起来不错,EXPLAIN很有希望。

虽然它显示“55856行”,但这只是EXPLAIN提供的估算值

key_len =1开始,您知道它使用复合索引的第一个字节作为相等/引用。

由于您的Extra字段中没有提及任何文件排序,因此您知道索引正在处理ORDER BY / sorting

如果您查看handler_%会话统计信息,则可以更好地了解实际读取的行数。

旁思:

由于你知道你最终要点击磁盘来检索你的行,如果99%的数据都有visibility=2(只是推测),你可能会得到同样好/快的结果索引仅在num_subscribers& num_items。或者如果你在num_subscribers上有一个索引,可以说是好/快,具体取决于它的基数/唯一性。

答案 1 :(得分:0)

我不认为EXPLAIN会查看OFFSETLIMIT子句。 EXPLAIN应该表明查询将如何执行,它使用了什么键,如何连接表等。LIMIT子句有点像一个帖子查询修饰符...现在我们知道了我们想要什么,只给他们第一个这么多。因此,rows字段包含查询中存在的可能行数。从那里,OFFSETLIMIT会选择您想要的具体内容。

我认为如果你执行了SELECT而没有EXPLAIN,你就会得到你想要的记录数。

答案 2 :(得分:0)

是的,问题是您的索引不正确。我的意思是你索引所有3个字段,你的选择查询只检查一个。在MySQL索引中,2行分别与索引3行不同。

尝试

CREATE TABLE IF NOT EXISTS `tbl_folder` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `owner_userid` int(11) NOT NULL,
  `name` varchar(63) NOT NULL,
  `description` text NOT NULL,
  `visibility` tinyint(4) NOT NULL DEFAULT '2',
  `num_items` int(11) NOT NULL DEFAULT '0',
  `num_subscribers` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `owner_userid` (`owner_userid`),
  KEY `vis_index` (`visibility`),
  KEY `vis_sub_item` (`num_subscribers`,`num_items`)
) ENGINE=InnoDB