Dlaczego pojawia się komunikat „Niemożliwe GDZIE zauważyłem po przeczytaniu tabel stałych” w zapytaniu wyjaśniającym?


27

Mam unikalny klucz złożony, taki jak fr (fromid, toid) w tabeli, kiedy uruchamiam zapytanie z wyjaśnieniem, otrzymuję następujący wynik:

Impossible WHERE noticed after reading const tables`

Zapytanie, które uruchomiłem:

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

Jakaś pomoc?

EDYCJA 1:
Kiedy używam poniższego zapytania:

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

Widzę USING WHEREzamiast poprzedniej wiadomości, ale kiedy używam poniższego zapytania:

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

Ponownie otrzymuję pierwszą impossible ...wiadomość! Co robią te nawiasy?

EDYCJA 2:

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

EDYCJA 3:
Jak mówią witryny mysql:

Niemożliwe GDZIE zauważono po odczytaniu tabel stałych

MySQL odczytał wszystkie tabele const (i systemowe) i zauważył, że klauzula WHERE jest zawsze fałszywa.

Ale w zapytaniu otrzymuję wynik, którego chcę, WHEREczęść nie false. Czy jest ktoś, kto mógłby to wyjaśnić i rzucić nieco światła na ten temat?


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

@RolandoMySQLDBA, będą using indexdodatkowe zamiastimpossible...
ALH

Odpowiedzi:


23

Otrzymujesz wiadomość

Niemożliwe GDZIE zauważono po odczytaniu tabel stałych

Jest to udokumentowane na stronie, którą już dowiązałeś .

MySQL przeczytał wszystkie const(i system) tabele i zauważył, że WHEREklauzula jest zawsze fałszywa

const tabele są zdefiniowane jako

Tabela ma co najwyżej jeden pasujący wiersz, który jest czytany na początku zapytania. ... constjest używany, gdy porównujesz wszystkie części a PRIMARY KEYlub UNIQUE indeksu ze stałymi wartościami.

Masz UNIQUE KEYna (fromid,toid). Zapytanie WHERE fromid=78 AND toid=60można spełnić, czytając ten unikalny indeks. Z otrzymanej wiadomości nie należy zwracać żadnych wyników.

Podobnie zapytanie WHERE fromid=60 and toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')może również użyć tego indeksu, aby zlokalizować interesujący wiersz (chociaż nadal ma rezydualny predykat do oceny, czy dowolny wiersz jest zgodny).

Twoje inne zapytanie jest inne

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

ANDma wyższy priorytet niż Or, więc jest to to samo co

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

Nie może już używać tego indeksu i ma inną semantykę, ponieważ zwróci wszystkie wiersze, is_approved IN ('f','t')niezależnie od wartości w innych kolumnach.


Więc jak mam na przykład powiedzieć: jeśli to, fromid=12 AND toid=78to sprawdź, is_approved='f'czy is_approved='t'lubis_approved='s'
ALH

1
@ john.locke: To jest twoje trzecie zapytanie: WHERE fromid=60 AND toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')można je również zapisać jako:WHERE fromid=60 AND toid=78 AND ( is_approved IN ('s', 'f', 't') )
ypercubeᵀᴹ

1
Dokładnie. Ponieważ żaden wiersz nie pasuje do fromid=60 AND toid=78części, więc nie jest konieczne dalsze sprawdzanie (dla is_approvedczęści).
ypercubeᵀᴹ

1
Nie można mieć wierszy s tamto. Jest wyjątkowe ograniczenie, (fromid,toid)więc na pewno byłoby ich maksymalnie jedno? A z wiadomości, którą mówisz, że otrzymujesz MySQL, nie sądzisz, że istnieje nawet jedna, która to robi. Czy masz na myśli, że masz kilka pasujących fromid=60wierszy i kilka pasujących wierszy, toid=78ale niekoniecznie te same wiersze?
Martin Smith

1
Być może jest to AND-ORzamieszanie . Może chcesz wszystkie wiersze, które mają fromid=60i wszystkie wiersze, które mają toid=78, a następnie od tych, zachować tylko te, które mają albo 's'albo 'f'albo t'is_approved? Jeśli tak, wypróbuj ten warunek:WHERE (fromid=60 OR toid=78) AND (is_approved IN ('s', 'f', 't'))
ypercubeᵀᴹ

5

MySql Explain wykorzystuje podane wartości dosłownie do przechodzenia między wierszami powiązanych tabel. Jeśli podasz stałą wartość / klucz, której nie ma w powiązanej tabeli, MySql Explain zatrzyma się z tym błędem. Po prostu zapytaj o powiązane tabele o wartości, które istnieją i podaj te w zapytaniu wyjaśniającym, a wszystko będzie działać zgodnie z oczekiwaniami.


3
Impossible WHERE noticed ...nie jest błędem. To część wyjaśnienia.
ypercubeᵀᴹ

3

Impossible WHERE noticed after reading const tables w wyjaśnieniu zapytania?

Ten błąd występuje z powodu umieszczenia niepoprawnej wartości w kolumnie, która jest albo kluczem podstawowym, albo kluczem unikatowym.

Spróbuj z poprawną wartością w whereklauzuli.


0

Wskakuję tak późno. Ale oto, co zauważyłem dla siebie.

Robiłem to zapytanie, a kolumna elementu była UNIKALNA.

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

które otrzymałoby Niemożliwe GDZIE zauważyłem po przeczytaniu tabel stałych

Wszystko, co musiałem zrobić, to zmienić „=” na „lubić”, a teraz używa mojego indeksu.

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

Czy nie używał indeksu z =?
ypercubeᵀᴹ

Nie dość szalone, że to nie było ... To było po prostu powiedzenie tego w wyjaśnieniu Niemożliwe GDZIE zauważyłem po przeczytaniu stałych tabel
RichardW11,

Tak, ale to „niemożliwe GDZIE” jest zwykle dobre. oznacza, że ​​zapytanie nie musi już czytać z tabel ani indeksów. Czy to było wolne? Jeśli nie, nie powinieneś się w ogóle martwić.
ypercubeᵀᴹ
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.