我在表中有一个像 fr(fromid,toid) 这样的唯一复合键,当我使用解释运行查询时,我得到以下结果:
Impossible WHERE noticed after reading const tables`
Run Code Online (Sandbox Code Playgroud)
我运行的查询:
explain SELECT rid FROM relationship WHERE fromid=78 AND toid=60
Run Code Online (Sandbox Code Playgroud)
有什么帮助吗?
EDIT1:
当我使用以下查询时:
explain SELECT rid FROM relationship WHERE fromid=60 and toid=78 AND is_approved='s' OR is_approved='f' OR is_approved='t'
Run Code Online (Sandbox Code Playgroud)
我看到的USING WHERE不是之前的消息,但是当我使用以下查询时:
explain SELECT rid FROM relationship WHERE fromid=60 and toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')
Run Code Online (Sandbox Code Playgroud)
我再次收到第一条impossible ...消息!这些括号在这里做什么?
编辑2:
CREATE TABLE `relationship` (
`rid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`fromid` mediumint(8) unsigned NOT NULL,
`toid` mediumint(8) unsigned NOT NULL,
`type` tinyint(3) unsigned NOT NULL,
`is_approved` char(1) NOT NULL,
PRIMARY KEY (`rid`),
UNIQUE KEY `fromid` (`fromid`,`toid`),
KEY `toid` (`toid`),
CONSTRAINT `relationship_ibfk_1` FOREIGN KEY (`fromid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `relationship_ibfk_2` FOREIGN KEY (`toid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
Run Code Online (Sandbox Code Playgroud)
EDIT3:
正如 mysql 站点所说:
不可能在阅读 const 表后注意到 WHERE
MySQL 已读取所有常量(和系统)表并注意到 WHERE 子句始终为假。
但是在查询中我得到了我想要的结果,WHERE部分不是false. 有没有人可以解释这一点并对这个主题有所了解?
Mar*_*ith 23
你收到消息
不可能在阅读 const 表后注意到 WHERE
这记录在您已经链接的页面中。
MySQL 已读取所有
const(和system)表并注意该WHERE子句始终为假
const 表定义为
该表最多有一个匹配行,在查询开始时读取。...
const用于将 aPRIMARY KEY或UNIQUE索引的所有部分与常量值进行比较。
你有一个UNIQUE KEY上 (fromid,toid)。WHERE fromid=78 AND toid=60可以通过读取这个唯一索引来满足查询。根据您收到的消息,这必须不返回任何结果。
类似地,查询WHERE fromid=60 and toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')也可以使用这个索引来定位感兴趣的行(尽管它仍然有一个残差谓词来评估任何要匹配的行)。
您的其他查询不同
SELECT rid
FROM relationship
WHERE fromid = 60
AND toid = 78
AND is_approved = 's'
OR is_approved = 'f'
OR is_approved = 't'
Run Code Online (Sandbox Code Playgroud)
AND具有比 更高的优先级Or,所以这与
SELECT rid
FROM relationship
WHERE ( ( fromid = 60 ) AND ( toid = 78 ) AND ( is_approved = 's' ) )
OR ( is_approved = 'f' )
OR ( is_approved = 't' )
Run Code Online (Sandbox Code Playgroud)
这不能再使用该索引并且具有不同的语义,因为它将返回任何行,is_approved IN ('f','t')而不管其他列中的值是什么。
小智 5
MySql Explain 使用您提供的值来遍历关联表的行。如果您提供了一个不在关联表中的常量/键值,MySql Explain 将因此错误而停止。只需查询关联表中确实存在的值并在您的解释查询中提供这些值,一切都会按预期工作。