Mengapa saya mendapatkan `Mustahil WHERE diperhatikan setelah membaca tabel const` dalam menjelaskan kueri?


27

Saya memiliki kunci majemuk unik seperti fr (fromid, toid) di tabel, ketika saya menjalankan kueri dengan menjelaskan saya mendapatkan hasil berikut:

Impossible WHERE noticed after reading const tables`

Kueri yang saya jalankan:

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

Ada bantuan?

EDIT1:
Ketika saya menggunakan permintaan di bawah ini:

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

Saya melihat USING WHEREbukannya pesan sebelumnya, tetapi ketika saya menggunakan kueri di bawah ini:

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

Saya kembali mendapatkan impossible ...pesan pertama ! Apa yang dilakukan kurung ini di sini?

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:
Seperti yang dikatakan situs mysql:

Mustahil DI MANA memperhatikan setelah membaca tabel const

MySQL telah membaca semua tabel const (dan sistem) dan perhatikan bahwa klausa WHERE selalu salah.

Tetapi dalam kueri saya mendapatkan hasil yang saya inginkan, WHEREbagiannya tidak false. Apakah ada seseorang yang bisa menjelaskan hal ini dan menjelaskan masalah ini?


Apa yang SELECT COUNT(1) FROM relationship WHERE fromid=78 AND toid=60;kembali ???
RolandoMySQLDBA

@RolandoMySQLDBA, akan ada using indextambahan bukanimpossible...
ALH

Jawaban:


23

Anda menerima pesannya

Mustahil DI MANA memperhatikan setelah membaca tabel const

Ini didokumentasikan di halaman yang sudah Anda tautkan .

MySQL telah membaca semua const(dan system) tabel dan memperhatikan bahwa WHEREklausa itu selalu salah

const tabel didefinisikan sebagai

Tabel memiliki paling banyak satu baris yang cocok, yang dibaca di awal kueri. ... constdigunakan ketika Anda membandingkan semua bagian dari PRIMARY KEYatau UNIQUE indeks dengan nilai konstan.

Anda punya UNIQUE KEYon (fromid,toid). Kueri aktif WHERE fromid=78 AND toid=60dapat dipenuhi dengan membaca indeks unik ini. Dari pesan yang Anda dapatkan ini tidak boleh membuahkan hasil.

Demikian pula, kueri WHERE fromid=60 and toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')juga dapat menggunakan indeks ini untuk menemukan baris yang diminati (meskipun masih memiliki predikat residual untuk dievaluasi jika ada baris yang cocok).

Permintaan Anda yang lain berbeda

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

ANDmemiliki prioritas lebih tinggi daripada Or, jadi ini sama dengan

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

Ini tidak lagi dapat menggunakan indeks itu dan memiliki semantik yang berbeda dalam hal itu akan mengembalikan setiap baris di mana is_approved IN ('f','t')terlepas dari apa nilai-nilai di kolom lain.


Jadi bagaimana saya harus mengatakan misalnya: jika fromid=12 AND toid=78kemudian memeriksa apakah is_approved='f'atau is_approved='t'atauis_approved='s'
ALH

1
@ john.locke: Itu adalah permintaan ketiga Anda: WHERE fromid=60 AND toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')yang juga dapat ditulis sebagai:WHERE fromid=60 AND toid=78 AND ( is_approved IN ('s', 'f', 't') )
ypercubeᵀᴹ

1
Persis. Karena tidak ada baris yang cocok dengan fromid=60 AND toid=78bagian sehingga tidak diperlukan pemeriksaan lebih lanjut (untuk is_approvedbagian itu).
ypercubeᵀᴹ

1
Anda tidak dapat memiliki baris s yang melakukan. Ada batasan unik (fromid,toid)sehingga pasti akan ada satu maksimum? Dan dari pesan yang Anda katakan Anda mendapatkan MySQL tidak berpikir bahwa ada yang melakukannya. Apakah maksud Anda memiliki beberapa baris yang cocok fromid=60dan beberapa baris yang cocok toid=78tetapi tidak harus baris yang sama?
Martin Smith

1
Mungkin ini AND-ORkebingungannya . Mungkin Anda ingin semua baris yang memiliki fromid=60dan semua baris yang memiliki toid=78dan kemudian dari orang-orang, hanya menjaga mereka yang memiliki baik 's'atau 'f'atau t'is_approved? Jika ya, coba kondisi ini:WHERE (fromid=60 OR toid=78) AND (is_approved IN ('s', 'f', 't'))
ypercubeᵀᴹ

5

Jelaskan MySql menggunakan nilai yang Anda berikan, secara harfiah, untuk melintasi baris dari tabel terkait. Jika Anda memberikan nilai konstan / kunci yang tidak ada dalam tabel terkait, MySql Explain akan berhenti dengan kesalahan ini. Cukup kueri tabel terkait untuk nilai-nilai yang ada dan berikan pada kueri Jelaskan dan semuanya akan berfungsi seperti yang diharapkan.


3
Impossible WHERE noticed ...bukan kesalahan. Itu bagian dari penjelasannya.
ypercubeᵀᴹ

3

Impossible WHERE noticed after reading const tables di jelaskan kueri?

Kesalahan ini terjadi karena nilai yang tidak valid diletakkan di kolom yang merupakan kunci utama atau kunci unik.

Coba dengan nilai yang benar dalam whereklausa.


0

Saya melompat ke selarut ini. Tapi inilah yang saya perhatikan untuk saya.

Saya melakukan kueri ini dan kolom item unik.

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

yang akan membuat Impossible WHERE diperhatikan setelah membaca tabel const

Yang harus saya lakukan adalah mengubah "=" menjadi "suka" dan sekarang menggunakan indeks saya.

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

Apakah itu tidak menggunakan indeks dengan =?
ypercubeᵀᴹ

Tidak cukup gila itu tidak .... Itu hanya mengatakan ini di menjelaskan Impossible WHERE perhatikan setelah membaca tabel const
RichardW11

Ya, tapi "WHERE WHERE" itu biasanya baik. berarti kueri tidak harus membaca lagi dari tabel atau indeks. Apakah itu lambat? Jika tidak, Anda tidak perlu khawatir sama sekali.
ypercubeᵀᴹ
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.