我在表中有一个独特的复合键,例如fr(fromid,toid),当我运行带有explain的查询时,得到以下结果:

Impossible WHERE noticed after reading const tables`


查询I ran:

explain SELECT rid FROM relationship WHERE fromid=78 AND toid=60   


有帮助吗?

EDIT1:
当我使用以下查询时:

explain SELECT rid FROM relationship WHERE fromid=60 and toid=78 AND is_approved='s'  OR is_approved='f' OR is_approved='t'


我看到的是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')  


我再次收到第一条impossible ...消息!这些括号在这里做什么?

EDIT2:

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


EDIT3:正如mysql网站所说:


在之后不可能出现的地方读取const表

MySQL已读取所有const(和系统)表,并注意WHERE
子句始终为false。


查询我得到我想要的结果,WHERE部分不是false。有没有人可以解释这一点并阐明了这个主题?

评论

从关系WHERE fromid = 78 AND toid = 60中选择COUNT(1)是什么?返回???

@RolandoMySQLDBA,将额外使用索引而不是不可能...

#1 楼

您正在获取消息


读取const表后不可能在哪里注意到


已记录在您已链接的页面中。


MySQL已读取所有const(和system)表,并注意WHERE子句始终为false


const表被定义为/>
该表最多具有一个匹配行,该行在查询的开始处读取。当将constPRIMARY KEY UNIQUE。通过读取此唯一索引可以满足对UNIQUE KEY的查询。从得到的消息中,它必须不返回任何结果。

类似地,查询(fromid,toid)也可以使用该索引来定位感兴趣的行(尽管它仍然具有剩余谓词,可以评估是否有任何匹配的行) )。

您的其他查询是不同的

SELECT rid
FROM   relationship
WHERE  fromid = 60
       AND toid = 78
       AND is_approved = 's'
        OR is_approved = 'f'
        OR is_approved = 't' 


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' ) 


它不能再使用该索引,并且具有不同的语义,因为它将返回AND所在的任何行,而与其他列中的值无关。

评论


那么我应该怎么说呢:如果它的fromid = 12和toid = 78然后检查is_approved ='f'或is_approved ='t'或is_approved ='s'

– ALH
2012年7月21日,下午4:51

@ john.locke:这是您的第三个查询:WHERE fromid = 60 AND toid = 78 AND(is_approved ='s'OR is_approved ='f'OR is_approved ='t')也可以写成:WHERE fromid = 60 AND toid = 78 AND(is_approved IN('s','f','t'))

–超立方体ᵀᴹ
2012年7月21日7:39



究竟。因为没有行与fromid = 60 AND toid = 78部分匹配,所以不需要进一步检查(对于is_approved部分)。

–超立方体ᵀᴹ
2012年7月21日在7:41



你不能有行。 (fromid,toid)有一个唯一的约束,所以肯定会有一个最大值吗?从您说的消息中得知,您得到MySQL的想法甚至都不存在。您是说有些行匹配fromid = 60,有些行匹配toid = 78,但不一定是相同的行?

–马丁·史密斯
2012年7月21日在7:49

也许这是AND-OR的混淆。也许您想要所有具有fromid = 60的行和所有具有toid = 78的行,然后从这些行中,仅保留具有is_approved的s或f或t的行?如果是,请尝试以下条件:WHERE(fromid = 60 OR toid = 78)AND(is_approved IN('s','f','t'))

–超立方体ᵀᴹ
2012年7月21日在8:52



#2 楼

MySql Explain实际上使用您提供的值来遍历关联表的行。如果提供的常数/键值不在关联表中,则MySql Explain会因该错误而停止。只需在关联的表中查询确实存在的值,并在Explain查询中提供这些值,一切将按预期工作。

评论


不可能在哪里注意到...不是错误。这是解释的一部分。

–超立方体ᵀᴹ
15年5月29日在16:58

#3 楼

Impossible WHERE noticed after reading const tables在解释查询中?

发生此错误是由于将无效值放在主键或唯一键的列上造成的。条款。

#4 楼

我跳得太晚了。但是,这就是我为我注意到的。

我正在执行此查询,并且项目列为UNIQUE。

SELECT `vari-groupid` FROM shop_item_variations_group where `item` = 'itemnu1' limit 1


在读取const表后,它会显示“不可能的WHERE”信息
/>
我要做的就是将“ =”更改为“ like”,现在它正在使用我的索引。

SELECT `vari-groupid` FROM shop_item_variations_group where `item` like 'itemnu1' limit 1


评论


是否不使用带有=的索引?

–超立方体ᵀᴹ
19 Mar 28 '19在15:23

还不够疯狂,不是……。这只是在解释const表后在“不可能的地方”中注意到了这一点

–RichardW11
19 Mar 28 '19 at 16:18

是的,但是“不可能的位置”通常很好。意味着查询不再需要从表或索引中读取任何内容。慢吗?如果没有,您根本不必担心。

–超立方体ᵀᴹ
19-3-28在16:25