¿Por qué me aparece "Imposible DONDE lo noté después de leer tablas const" en la consulta de explicación?

27

Tengo una clave compuesta única como fr (fromid, toid) en la tabla, cuando ejecuto la consulta con explicar obtengo el siguiente resultado:

Impossible WHERE noticed after reading const tables`

La consulta que ejecuté:

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

¿Alguna ayuda?

EDITAR1:
cuando uso la siguiente consulta:

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

Veo en USING WHERElugar del mensaje anterior, pero cuando uso la siguiente consulta:

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

De nuevo recibo el primer impossible ...mensaje! ¿Qué hacen estos paréntesis aquí?

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

EDITAR3:
Como dice el sitio mysql:

Imposible DONDE se notó después de leer tablas const

MySQL ha leído todas las tablas const (y del sistema) y ha notado que la cláusula WHERE siempre es falsa.

Pero en la consulta obtengo el resultado que quiero, la WHEREparte no lo es false. ¿Hay alguien que pueda explicar esto y arrojar algo de luz sobre el tema?

ALH
fuente
¿Qué SELECT COUNT(1) FROM relationship WHERE fromid=78 AND toid=60;devuelve?
RolandoMySQLDBA
@RolandoMySQLDBA, habrá más using indexen lugar deimpossible...
ALH

Respuestas:

23

Estas recibiendo el mensaje

Imposible DONDE se notó después de leer tablas const

Esto está documentado en la página que ya ha vinculado .

MySQL ha leído todas las tablas const(y system) y observa que la WHEREcláusula siempre es falsa

const las tablas se definen como

La tabla tiene como máximo una fila coincidente, que se lee al comienzo de la consulta. ... constse utiliza cuando se comparan todas las partes de una PRIMARY KEYo UNIQUE índice a valores constantes.

Tienes un UNIQUE KEYencendido (fromid,toid). La consulta WHERE fromid=78 AND toid=60se puede satisfacer leyendo este índice único. Del mensaje que está recibiendo esto no debe devolver resultados.

De manera similar, la consulta WHERE fromid=60 and toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')también puede usar este índice para localizar la fila de interés (aunque todavía tiene un predicado residual para evaluar si alguna fila coincide).

Su otra consulta es diferente

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

ANDtiene una precedencia mayor que Or, por lo que es lo mismo que

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

Esto ya no puede usar ese índice y tiene una semántica diferente, ya que devolverá cualquier fila donde is_approved IN ('f','t')sea ​​que sean los valores en las otras columnas.

Martin Smith
fuente
Entonces, ¿cómo debería decir, por ejemplo: si es fromid=12 AND toid=78entonces verifique si is_approved='f'o is_approved='t'o?is_approved='s'
ALH
1
@ john.locke: Esa es su tercera consulta: WHERE fromid=60 AND toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')que también se puede escribir como:WHERE fromid=60 AND toid=78 AND ( is_approved IN ('s', 'f', 't') )
ypercubeᵀᴹ
1
Exactamente. Debido a que ninguna fila coincide con la fromid=60 AND toid=78parte, no es necesario realizar más comprobaciones (para la is_approvedparte).
ypercubeᵀᴹ
1
No se puede tener fila s que lo hacen. ¿Existe una restricción única (fromid,toid)para que seguramente haya un máximo de uno? Y a partir del mensaje que dice que está recibiendo MySQL, no cree que haya siquiera uno que lo haga. ¿Quiere decir que tiene algunas filas que coinciden fromid=60y algunas filas que coinciden toid=78pero no necesariamente las mismas filas?
Martin Smith
1
Quizás esta sea la AND-ORconfusión . ¿Quizás quiera todas las filas que tienen fromid=60y todas las filas que tienen toid=78y luego de ellas, mantener solo las que tienen 's'o está 'f'o está t'aprobado? En caso afirmativo, intente esta condición:WHERE (fromid=60 OR toid=78) AND (is_approved IN ('s', 'f', 't'))
ypercubeᵀᴹ
5

MySql Explain utiliza los valores que proporciona, literalmente, para recorrer las filas de las tablas asociadas. Si proporciona un valor constante / clave que no está en la tabla asociada, MySql Explain se detendrá con este error. Simplemente consulte en la (s) tabla (s) asociada (s) los valores que existen y proporcione aquellos en su consulta de Explain y todo funcionará como se espera.

grwww
fuente
3
Impossible WHERE noticed ...No es un error. Es parte de la explicación.
ypercubeᵀᴹ
3

Impossible WHERE noticed after reading const tables en explicar consulta?

Este error se produce debido a que se coloca un valor no válido en una columna que es clave principal o clave única.

Intente con un valor correcto en la wherecláusula.

Rjnish Kumar
fuente
0

Estoy entrando tan tarde. Pero aquí está lo que noté por mí.

Estaba haciendo esta consulta y la columna del elemento era ÚNICA.

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

que obtendría lo imposible DONDE se notó después de leer las tablas constantes

Todo lo que tenía que hacer era cambiar "=" a "me gusta" y ahora está usando mi índice.

SELECT `vari-groupid` FROM shop_item_variations_group where `item` like 'itemnu1' limit 1
RichardW11
fuente
¿No estaba usando el índice con el =?
ypercubeᵀᴹ
No es lo suficientemente loco, no fue ... Solo decía esto en la explicación Imposible DONDE se notó después de leer las tablas constantes
RichardW11
Sí, pero ese "DONDE imposible" suele ser bueno. significa que la consulta no tiene que leer más de las tablas o índices. ¿Fue lento? Si no, no debes preocuparte en absoluto.
ypercubeᵀᴹ