MySQL多列索引无法正常工作(如预期)吗?
-
10-10-2019 - |
题
我有这样的桌子
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 and num_items有一个索引,因此我希望只有前15行只能被查看,而是说明了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个字段索引看起来不错, EXPLAIN
很有希望。
尽管它说“ 55856行”,但这只是一个 估计 由...提供 EXPLAIN
.
自从 key_len =1
, ,您知道它使用化合物索引的第一个字节作为平等/参考。
由于您的 Extra
领域,你知道 ORDER BY
/排序 是 被指数处理。
如果您检查您的 handler_%
会话统计信息,您将对实际阅读多少行有更好的了解。
侧面想法:
由于您知道您最终会击中磁盘以检索行,如果您的数据中有99% visibility=2
(只是猜测),您可能会以一个复合索引获得同样好/快速的结果 num_subscribers
& num_items
. 。或说明您有单个索引,可以说是好/快。 num_subscribers
, ,取决于其基数/独特性。
其他提示
我不认为 EXPLAIN
看着 OFFSET
或者 LIMIT
条款。 EXPLAIN
应该指示如何执行查询,使用的键,如何连接表等。 LIMIT
条款有点像一个邮政查询修饰符...现在我们知道了我们想要的东西,只给了em第一个。因此,行字段包含查询中存在的可能行数。从那里, OFFSET
和 LIMIT
会选择您想要的特定特定方法。
我想,如果您执行了 SELECT
没有 EXPLAIN
, ,您将获得想要的记录数量。
是的,问题是您的索引不正确。我的意思是您索引了所有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
不隶属于 StackOverflow