为什么在解释查询中阅读 const 表后我会注意到“不可能的地方”?

Ali*_*eza 27 mysql explain

我在表中有一个像 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 KEYUNIQUE 索引的所有部分与常量值进行比较。

你有一个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 将因此错误而停止。只需查询关联表中确实存在的值并在您的解释查询中提供这些值,一切都会按预期工作。

  • `不可能在哪里注意到......`不是错误。这是解释的一部分。 (3认同)