Pourquoi est-ce que j'obtiens `Impossible OERE je l'ai remarqué après avoir lu les tables const` dans la requête d'explication?


27

J'ai une clé composée unique comme fr (fromid, toid) dans la table, lorsque j'exécute la requête avec expliquer, j'obtiens le résultat suivant:

Impossible WHERE noticed after reading const tables`

La requête que j'ai exécutée:

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

De l'aide?

EDIT1:
Lorsque j'utilise la requête ci-dessous:

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

Je vois à la USING WHEREplace du message précédent, mais lorsque j'utilise la requête ci-dessous:

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

Je reçois à nouveau le premier impossible ...message! Que font ces parenthèses ici?

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:
Comme le dit le site mysql:

Impossible O noticed remarqué après avoir lu les tables const

MySQL a lu toutes les tables const (et système) et remarque que la clause WHERE est toujours fausse.

Mais dans la requête j'obtiens le résultat que je veux, la WHEREpièce ne l'est pas false. Y a-t-il quelqu'un qui pourrait expliquer cela et faire la lumière sur le sujet?


Que SELECT COUNT(1) FROM relationship WHERE fromid=78 AND toid=60;revient ???
RolandoMySQLDBA

@RolandoMySQLDBA, il y aura using indexen extra au lieu deimpossible...
ALH

Réponses:


23

Vous recevez le message

Impossible O noticed remarqué après avoir lu les tables const

Ceci est documenté dans la page que vous avez déjà liée .

MySQL a lu toutes les const(et system) tables et remarque que la WHEREclause est toujours fausse

const les tables sont définies comme

La table a au plus une ligne correspondante, qui est lue au début de la requête. ... constest utilisé lorsque vous comparez toutes les parties d'un index PRIMARY KEYou UNIQUEà des valeurs constantes.

Vous avez un UNIQUE KEYsur (fromid,toid). La requête sur WHERE fromid=78 AND toid=60peut être satisfaite en lisant cet index unique. Du message que vous obtenez, cela ne doit retourner aucun résultat.

De même, la requête WHERE fromid=60 and toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')peut également utiliser cet index pour localiser la ligne d'intérêt (bien qu'il ait toujours un prédicat résiduel à évaluer si une ligne devait correspondre).

Votre autre requête est différente

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

ANDa une priorité plus élevée que Or, c'est donc la même chose que

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

Cela ne peut plus utiliser cet index et a une sémantique différente en ce sens qu'il renverra toutes les lignes où que is_approved IN ('f','t')soient les valeurs dans les autres colonnes.


Alors, comment dois-je dire par exemple: si c'est fromid=12 AND toid=78alors vérifier si is_approved='f'ou is_approved='t'ouis_approved='s'
ALH

1
@ john.locke: C'est votre troisième requête: WHERE fromid=60 AND toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')qui peut aussi s'écrire:WHERE fromid=60 AND toid=78 AND ( is_approved IN ('s', 'f', 't') )
ypercubeᵀᴹ

1
Exactement. Parce qu'aucune ligne ne correspond à la fromid=60 AND toid=78pièce, aucune vérification supplémentaire n'est nécessaire (pour la is_approvedpièce).
ypercubeᵀᴹ

1
Vous ne pouvez pas avoir rangée s qui le font. Il y a une contrainte unique (fromid,toid)donc il y en aurait sûrement un maximum? Et d'après le message que vous dites que vous obtenez MySQL, vous ne pensez pas qu'il y en ait même un. Voulez-vous dire que vous avez des lignes qui correspondent fromid=60et des lignes qui correspondent, toid=78mais pas nécessairement les mêmes lignes?
Martin Smith

1
C'est peut-être la AND-ORconfusion . Peut-être que vous voulez toutes les lignes qui ont fromid=60et toutes les lignes qui ont toid=78et ensuite de celles-ci, ne gardez que celles qui ont 's'ou 'f'ou t'est_approuvé? Si oui, essayez cette condition:WHERE (fromid=60 OR toid=78) AND (is_approved IN ('s', 'f', 't'))
ypercubeᵀᴹ

5

MySql Explain utilise littéralement les valeurs que vous fournissez pour parcourir les lignes des tables associées. Si vous fournissez une valeur constante / clé qui n'est pas dans la table associée, MySql Explain s'arrêtera avec cette erreur. Recherchez simplement les tables associées pour les valeurs qui existent et fournissez-les dans votre requête Explain et tout fonctionnera comme prévu.


3
Impossible WHERE noticed ...n'est pas une erreur. Cela fait partie de l'explication.
ypercubeᵀᴹ

3

Impossible WHERE noticed after reading const tables dans expliquer la requête?

Cette erreur se produit en raison de la valeur non valide placée sur une colonne qui sont soit la clé primaire soit la clé unique.

Essayez avec une valeur correcte dans la whereclause.


0

Je saute trop tard. Mais voici ce que j'ai remarqué pour moi.

Je faisais cette requête et la colonne de l'article était UNIQUE.

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

qui obtiendrait l' impossible où remarqué après avoir lu les tables const

Tout ce que j'avais à faire était de changer "=" en "j'aime" et il utilise maintenant mon index.

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

N'utilisait-il pas l'index avec le =?
ypercubeᵀᴹ

Pas assez fou, ce n'était pas ... C'était juste en disant cela dans l'explication Impossible O Impossible on l'a remarqué après avoir lu les tables const
RichardW11

Oui, mais cet "impossible OERE" est généralement bon. signifie que la requête n'a plus besoin de lire les tables ou les index. C'était lent? Sinon, vous ne devriez pas vous inquiéter du tout.
ypercubeᵀᴹ
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.