我想了解MySQL在使用ORDER BY时会在什么时候使用索引列。
例如,查询
SELECT * FROM A
INNER JOIN B ON B.id = A.id
WHERE A.status = 1 AND A.name = 'Mike' AND A.created_on BETWEEN '2014-10-01 00:00:00' AND NOW()
ORDER BY A.accessed_on DESC
根据我的知识,上述查询的一个好索引是表A (id, status, name created_on, accessed_on)
上的索引和B.id
上的另一个索引。
我也理解SQL执行遵循以下顺序。但我不确定订单选择和订单是如何运作的。
问题
使用id
列启动索引会不会更好,或者在这种情况下无关紧要因为在{JOIN之前首先执行WHERE
?或者它应该是
第二个问题,access_on列应该在索引组合的开头,结尾还是中间?或id
列是否应在WHERE
子句中的所有列之后?
我很感激详细的答案,所以我可以理解MySQL / SQL的执行级别
已更新
我向表A和B添加了几百万条记录然后我添加了多个索引以查看哪个是最佳索引。但是,MySQL似乎喜欢索引id_2 (ie. (status, name, created_on, id, accessed_on))
它似乎正在应用where并且它会发现它需要和索引状态,名称,created_on然后它使用INNER JOIN
并且它将使用id
索引,然后是第一个3.最后,它会将visited_on作为最后一列。所以索引(status, name, created_on, id, accessed_on)
符合相同的执行顺序
这是表格结构
CREATE TABLE `a` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`status` int(2) NOT NULL,
`name` varchar(255) NOT NULL,
`created_on` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`accessed_on` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `status` (`status`,`name`),
KEY `status_2` (`status`,`name`,`created_on`),
KEY `status_3` (`status`,`name`,`created_on`,`accessed_on`),
KEY `status_4` (`status`,`name`,`accessed_on`),
KEY `id` (`id`,`status`,`name`,`created_on`,`accessed_on`),
KEY `id_2` (`status`,`name`,`created_on`,`id`,`accessed_on`)
) ENGINE=InnoDB AUTO_INCREMENT=3135750 DEFAULT CHARSET=utf8
CREATE TABLE `b` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3012644 DEFAULT CHARSET=utf8
答案 0 :(得分:1)
此查询的最佳索引是:A(status, name, created_on)
和B(id)
。这些索引将满足where
子句,并使用连接的索引B
。
此索引不会用于排序。使用任何索引进行排序有两个主要障碍。第一个是加入。第二个是created_on
上的不平等。有些数据库可能会在A(status, name, accessed_on)
上使用索引,但我认为MySQL不够聪明。
您不希望id
作为索引中的第一列。这排除了使用索引对A
进行过滤,因为id
用于join
而不是where
。