Tại sao tôi nhận được `Impossible WHERE chú ý sau khi đọc const bảng` trong truy vấn giải thích?


27

Tôi có một khóa ghép duy nhất như fr (fromid, toid) trong bảng, khi tôi chạy truy vấn với giải thích tôi nhận được kết quả sau:

Impossible WHERE noticed after reading const tables`

Truy vấn tôi đã chạy:

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

Có ai giúp đỡ không?

EDIT1:
Khi tôi sử dụng truy vấn dưới đây:

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

Tôi thấy USING WHEREthay vì tin nhắn trước đó, nhưng khi tôi sử dụng truy vấn bên dưới:

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

Tôi lại nhận được impossible ...tin nhắn đầu tiên ! Những dấu ngoặc đơn này làm gì ở đây?

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: Như trang mys mys
nói:

Không thể nhận thấy WHERE sau khi đọc bảng const

MySQL đã đọc tất cả các bảng const (và hệ thống) và lưu ý rằng mệnh đề WHERE luôn luôn sai.

Nhưng trong truy vấn tôi nhận được kết quả tôi muốn, WHEREphần thì không false. Có ai đó có thể giải thích điều này và làm sáng tỏ chủ đề này?


Trả lại cái gì SELECT COUNT(1) FROM relationship WHERE fromid=78 AND toid=60;???
RolandoMySQLDBA

@RolandoMySQLDBA, sẽ có using indexthêm thay vìimpossible...
ALH

Câu trả lời:


23

Bạn đang nhận được tin nhắn

Không thể nhận thấy WHERE sau khi đọc bảng const

Điều này được ghi lại trong trang bạn đã liên kết .

MySQL đã đọc tất cả const(và system) bảng và lưu ý rằng WHEREmệnh đề luôn luôn sai

const bảng được định nghĩa là

Bảng có nhiều nhất một hàng khớp, được đọc khi bắt đầu truy vấn. ... constĐược sử dụng khi bạn so sánh tất cả các phần của một PRIMARY KEYhoặc UNIQUE chỉ mục với các giá trị không đổi.

Bạn có một UNIQUE KEYtrên (fromid,toid). Truy vấn trên WHERE fromid=78 AND toid=60có thể được thỏa mãn bằng cách đọc chỉ mục duy nhất này. Từ tin nhắn bạn nhận được điều này phải trả lại không có kết quả.

Tương tự, truy vấn WHERE fromid=60 and toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')cũng có thể sử dụng chỉ mục này để xác định hàng quan tâm (mặc dù nó vẫn có một vị từ còn lại để đánh giá là bất kỳ hàng nào phù hợp).

Truy vấn khác của bạn là khác nhau

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

ANDcó quyền ưu tiên cao hơn Or, vì vậy điều này giống như

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

Điều này không còn có thể sử dụng chỉ mục đó và có ngữ nghĩa khác nhau ở chỗ nó sẽ trả về bất kỳ hàng nào trong đó is_approved IN ('f','t')không phân biệt giá trị trong các cột khác là gì.


Vì vậy, làm thế nào tôi nên nói ví dụ: nếu nó fromid=12 AND toid=78thì kiểm tra xem is_approved='f'hoặc is_approved='t'hayis_approved='s'
ALH

1
@ john.locke: Đó là truy vấn thứ ba của bạn: WHERE fromid=60 AND toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')cũng có thể được viết là:WHERE fromid=60 AND toid=78 AND ( is_approved IN ('s', 'f', 't') )
ypercubeᵀᴹ

1
Chính xác. Vì không có hàng nào khớp với fromid=60 AND toid=78phần nên không cần kiểm tra thêm (đối với is_approvedphần).
ypercubeᵀᴹ

1
Bạn không thể có hàng s mà làm. Có một ràng buộc duy nhất trên (fromid,toid)vì vậy chắc chắn sẽ có tối đa một? Và từ tin nhắn mà bạn nói rằng bạn đang nhận được MySQL không nghĩ rằng thậm chí còn có một. Bạn có nghĩa là bạn có một số hàng khớp fromid=60và một số hàng khớp với nhau toid=78nhưng không nhất thiết phải là cùng một hàng?
Martin Smith

1
Có lẽ đây là sự AND-ORnhầm lẫn . Có lẽ bạn muốn tất cả các hàng có fromid=60và tất cả các hàng có toid=78và sau đó từ các hàng đó, chỉ giữ lại những hàng có 's'hoặc 'f'hoặc t'is_approved? Nếu có, hãy thử điều kiện này:WHERE (fromid=60 OR toid=78) AND (is_approved IN ('s', 'f', 't'))
ypercubeᵀᴹ

5

MySql Giải thích sử dụng các giá trị bạn cung cấp, theo nghĩa đen, để duyệt qua các hàng của các bảng được liên kết. Nếu bạn cung cấp một giá trị hằng / khóa không có trong bảng liên kết, MySql Giải thích sẽ dừng với lỗi này. Chỉ cần truy vấn (các) bảng được liên kết để biết các giá trị tồn tại và cung cấp các giá trị trong truy vấn Giải thích của bạn và mọi thứ sẽ hoạt động như mong đợi.


3
Impossible WHERE noticed ...không phải là một lỗi. Đó là một phần của lời giải thích.
ypercubeᵀᴹ

3

Impossible WHERE noticed after reading const tables trong giải thích truy vấn?

Lỗi này xảy ra do giá trị không hợp lệ được đặt trên một cột là khóa chính hoặc khóa duy nhất.

Hãy thử với một giá trị chính xác trong wheremệnh đề.


0

Tôi nhảy vào đây muộn. Nhưng đây là những gì tôi nhận thấy cho tôi.

Tôi đã thực hiện truy vấn này và cột mục là ĐỘC ĐÁO.

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

cái mà sẽ nhận được Impossible WHERE được chú ý sau khi đọc các bảng const

Tất cả những gì tôi phải làm là thay đổi "=" thành "thích" và hiện tại nó đang sử dụng chỉ mục của tôi.

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

Có phải nó không sử dụng chỉ mục với =?
ypercubeᵀᴹ

Không có gì đủ điên rồ cả .... Nó chỉ nói điều này trong phần giải thích Impossible WHERE nhận thấy sau khi đọc các bảng const
RichardW11

Có, nhưng "không thể ở đâu" thường tốt. có nghĩa là truy vấn không phải đọc thêm từ các bảng hoặc chỉ mục. Có chậm không? Nếu không, bạn không nên lo lắng.
ypercubeᵀᴹ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.