Explainクエリで「constテーブルを読み取った後に「不可能なWHERE」に気付くのはなぜですか?


27

テーブルにfr(fromid、toid)のような一意の複合キーがあり、explainを使用してクエリを実行すると、次の結果が得られます。

Impossible WHERE noticed after reading const tables`

私が実行したクエリ:

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テーブルの読み取り後に気付かない可能性のあるWHERE

MySQLはすべてのconst(およびシステム)テーブルを読み取り、WHERE句が常にfalseであることを確認しました。

しかし、私が望む結果を得るクエリでは、WHERE部分はそうではありませんfalse。これを説明し、主題に光を当てることができる人はいますか?


何がSELECT COUNT(1) FROM relationship WHERE fromid=78 AND toid=60;返されますか?
RolandoMySQLDBA

@RolandoMySQLDBAは、あるでしょうusing index余分の代わりにimpossible...
ALH

回答:


23

メッセージを受け取っています

constテーブルの読み取り後に気付かない可能性のあるWHERE

これは、すでにリンクたページに記載されています

MySQLはすべてのconst(およびsystem)テーブルを読み取り、WHERE句が常にfalseであることを確認しました

const テーブルは次のように定義されます

テーブルには最大で1つの一致する行があり、クエリの開始時に読み取られます。... constは、PRIMARY 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' 

ANDの優先順位はより大きいOrため、これは次と同じです

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

これは、返すようにインデックスとは異なる意味を持っていることをもはや使用することができます任意のis_approved IN ('f','t')の他の列の値が何であるかにかかわらずに。


たとえば、どのように言う必要があります:そのfromid=12 AND toid=78場合チェックするかis_approved='f'is_approved='t'またはis_approved='s'
-ALH

1
@ john.locke:これは3番目のクエリです。次の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') )
ypercubeᵀᴹ12年

1
まさに。fromid=60 AND toid=78パーツに一致する行がないため、それ以上のチェックは必要ありません(is_approvedパーツに対して)。
ypercubeᵀᴹ

1
あなたは行することはできませんありません。に一意の制約がある(fromid,toid)ので、確実に最大1つになるでしょうか?また、MySQLを取得しているというメッセージから、MySQLにはそれがあるとさえ思わない。一致fromid=60する行と一致するtoid=78が必ずしも同じ行ではない行があることを意味しますか?
マーティンスミス

1
おそらくこれはAND-OR混乱です。たぶん、あなたは持っているすべての行と持っfromid=60ているすべての行toid=78、そしてそれらのいずれか、's'または'f'orまたはt'is_approved を持つものだけを保持したいですか?はいの場合、この条件を試してください。WHERE (fromid=60 OR toid=78) AND (is_approved IN ('s', 'f', 't'))
ypercubeᵀᴹ12年

5

MySql Explainは、指定された値を文字通り使用して、関連するテーブルの行を走査します。関連付けられたテーブルにない定数/キー値を指定すると、MySql Explainはこのエラーで停止します。関連付けられたテーブルに存在する値を照会し、Explainクエリでそれらを提供するだけで、すべてが期待どおりに機能します。


3
Impossible WHERE noticed ...エラーではありません。これは説明の一部です。
ypercubeᵀᴹ

3

Impossible WHERE noticed after reading const tables Explainクエリで?

このエラーは、主キーまたは一意キーのいずれかである列に無効な値が設定されているために発生します。

where句の正しい値を試してください。


0

私はこれに飛び込んでいます。しかし、ここに私が気づいたことがあります。

このクエリを実行していて、アイテム列は一意でした。

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

これはなるだろうconstのテーブルを読んだ後に気づいWHEREインポッシブルを

「=」を「いいね」に変更するだけで、今はインデックスを使用しています。

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

インデックスを使用していませんでした=か?
ypercubeᵀᴹ

constのテーブル読んだ後に気づいたそれは....それはちょうどでこれを言っていたていなかったん狂気の十分なんインポッシブル説明
RichardW11

はい、しかしその「不可能なWHERE」は通常良いです。は、クエリがテーブルまたはインデックスからこれ以上読み取る必要がないことを意味します。遅かった?そうでない場合は、まったく心配しないでください。
ypercubeᵀᴹ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.