MySQL 解释计划、多字段索引和 OR 子句的问题
Issue with MySQL explain plan, multiple-field indices and OR clause
我有一个我不明白的解释计划结果。我有以下 table 保存从 senders
发送到 recipients
的消息。
CREATE TABLE `message` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`message_read` bit(1) NOT NULL,
`send_date` datetime NOT NULL,
`text` varchar(500) NOT NULL,
`version` int(11) DEFAULT NULL,
`recipient` bigint(20) NOT NULL,
`sender` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `index4` (`recipient`,`sender`) USING BTREE,
KEY `index5` (`sender`,`recipient`) USING BTREE,
CONSTRAINT `FK_a3km2kv42i1xu571ta911f9dc` FOREIGN KEY (`sender`) REFERENCES `member` (`id`),
CONSTRAINT `FK_hn9roqyj131hnul5fuwgwlv9e` FOREIGN KEY (`recipient`) REFERENCES `member` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8;
这是我的解释计划:
explain select *
from
message m
where
(
m.sender = 1
and m.recipient= 2
)
or (
m.recipient = 1
and m.sender= 2
)
这是我的解释计划的结果:
我不确定为什么 key
字段是 null
(possible_keys
确实提到了我想使用的索引)。
如何确保使用 index4
和 index5
索引?
编辑 1:
我已经在 table 中插入了一些行。以下说明:
explain select *
from
message m FORCE INDEX(index4)
where
(
m.sender = 1
and m.recipient= 2
)
or (
m.sender= 2
and m.recipient = 1
)
现在产生以下结果:
1 SIMPLE m range index4 index4 16 32 Using where
为了强制使用索引,可以使用FORCE INDEX...
SELECT *
FROM message FORCE INDEX(index4)
WHERE ((recipient = 2 AND sender = 1) OR (recipient=1 AND sender = 2));
在 32 行的 table 上,这可能比完整的 table 扫描效率低。
我有一个我不明白的解释计划结果。我有以下 table 保存从 senders
发送到 recipients
的消息。
CREATE TABLE `message` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`message_read` bit(1) NOT NULL,
`send_date` datetime NOT NULL,
`text` varchar(500) NOT NULL,
`version` int(11) DEFAULT NULL,
`recipient` bigint(20) NOT NULL,
`sender` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `index4` (`recipient`,`sender`) USING BTREE,
KEY `index5` (`sender`,`recipient`) USING BTREE,
CONSTRAINT `FK_a3km2kv42i1xu571ta911f9dc` FOREIGN KEY (`sender`) REFERENCES `member` (`id`),
CONSTRAINT `FK_hn9roqyj131hnul5fuwgwlv9e` FOREIGN KEY (`recipient`) REFERENCES `member` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8;
这是我的解释计划:
explain select *
from
message m
where
(
m.sender = 1
and m.recipient= 2
)
or (
m.recipient = 1
and m.sender= 2
)
这是我的解释计划的结果:
我不确定为什么 key
字段是 null
(possible_keys
确实提到了我想使用的索引)。
如何确保使用 index4
和 index5
索引?
编辑 1:
我已经在 table 中插入了一些行。以下说明:
explain select *
from
message m FORCE INDEX(index4)
where
(
m.sender = 1
and m.recipient= 2
)
or (
m.sender= 2
and m.recipient = 1
)
现在产生以下结果:
1 SIMPLE m range index4 index4 16 32 Using where
为了强制使用索引,可以使用FORCE INDEX...
SELECT *
FROM message FORCE INDEX(index4)
WHERE ((recipient = 2 AND sender = 1) OR (recipient=1 AND sender = 2));
在 32 行的 table 上,这可能比完整的 table 扫描效率低。