mysql 多列索引不起作用(如预期的那样)?
Posted
技术标签:
【中文标题】mysql 多列索引不起作用(如预期的那样)?【英文标题】:mysql multi column index not working (as expected)? 【发布时间】:2011-05-22 10:44:13 【问题描述】:我有一张这样的桌子
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
【问题讨论】:
将您的 SQL 包装在“代码块”标签中,以便我们更容易阅读。它有助于它脱颖而出并使其更易于阅读。 【参考方案1】:您的 3 字段索引看起来不错,EXPLAIN
很有希望。
虽然它说“55856 行”,但这只是EXPLAIN
提供的估计。
由于key_len =1
,您知道它使用复合索引的第一个字节作为相等/引用。
由于您的Extra
字段中没有提到文件排序,因此您知道ORDER BY
/sorting 正在 由索引处理。
如果您检查 handler_%
会话统计信息,您将更好地了解实际读取了多少行。
旁白:
既然您知道您最终会使用磁盘来检索您的行,那么如果您的 99% 的数据都有 visibility=2
(只是推测),那么您可能会通过复合索引获得同样好的/快速的结果在num_subscribers
和num_items
。或者,如果您在 num_subscribers
上有一个索引,则可以说是好/快,这取决于它的基数/唯一性。
【讨论】:
【参考方案2】:我认为EXPLAIN
不会查看OFFSET
或LIMIT
子句。 EXPLAIN
应该指示查询将如何执行,它使用什么键,表如何连接等。LIMIT
子句有点像查询后修饰符......现在我们知道我们想要什么,只给他们第一个这么多。因此,rows 字段包含查询中可能存在的行数。从那里,OFFSET
和 LIMIT
会选择你想要的特定的。
我想如果你在没有EXPLAIN
的情况下执行你的SELECT
,你会得到你想要的记录数。
【讨论】:
【参考方案3】:是的,问题是您的索引不正确。我的意思是您索引了所有 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
【讨论】:
以上是关于mysql 多列索引不起作用(如预期的那样)?的主要内容,如果未能解决你的问题,请参考以下文章