ทำไมฉันถึงได้รับ 'Impossible WHERE สังเกตหลังจากอ่าน const tables' ในคำอธิบายการสืบค้น?


27

ฉันมีคีย์ผสมที่ไม่ซ้ำกันเช่น fr (fromid, toid) ในตารางเมื่อฉันเรียกใช้แบบสอบถามด้วยคำอธิบายฉันได้รับผลลัพธ์ต่อไปนี้:

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

MySQL ได้อ่านตาราง const (และระบบ) ทั้งหมดและสังเกตว่าประโยค WHERE เป็นเท็จเสมอ

แต่ในแบบสอบถามที่ฉันได้รับผลที่ฉันต้องการที่ส่วนหนึ่งไม่ได้WHERE falseมีใครบ้างที่สามารถอธิบายเรื่องนี้และให้ความกระจ่างในเรื่องนี้ได้บ้าง?


SELECT COUNT(1) FROM relationship WHERE fromid=78 AND toid=60;ผลตอบแทนอะไร???
RolandoMySQLDBA

@RolandoMySQLDBA จะมีการusing indexเพิ่มพิเศษแทนimpossible...
ALH

คำตอบ:


23

คุณได้รับข้อความ

เป็นไปไม่ได้ที่จะสังเกตเห็นหลังจากอ่านตาราง const

นี้ถูกบันทึกไว้ในหน้าเว็บที่คุณเชื่อมโยงอยู่แล้ว

MySQL อ่านตารางทั้งหมดconst(และsystem) และสังเกตว่าWHEREประโยคนั้นเป็นเท็จเสมอ

const ตารางถูกกำหนดเป็น

ตารางมีแถวที่ตรงกันไม่เกินหนึ่งแถวซึ่งจะถูกอ่านเมื่อเริ่มต้นคิวรี ... constใช้เมื่อคุณเปรียบเทียบส่วนต่าง ๆ ของ a 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: นั่นคือคำถามที่สามของคุณ: 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ᵀᴹ

1
เผง เนื่องจากไม่มีแถวตรงกับfromid=60 AND toid=78ส่วนจึงไม่จำเป็นต้องตรวจสอบเพิ่มเติม (สำหรับชิ้นis_approvedส่วน)
ypercubeᵀᴹ

1
คุณไม่สามารถมีแถวsที่ทำ มีข้อ จำกัด ที่ไม่เหมือนใคร(fromid,toid)ดังนั้นจะมีจำนวนสูงสุดอย่างแน่นอนหรือไม่ และจากข้อความที่คุณบอกว่าคุณได้รับ MySQL ไม่คิดว่ามีแม้แต่สิ่งเดียวที่ทำได้ คุณหมายถึงว่าคุณมีแถวที่ตรงกันfromid=60และบางแถวที่ตรงกันtoid=78แต่ไม่จำเป็นต้องเป็นแถวเดียวกันหรือไม่
Martin Smith

1
บางทีนี่อาจเป็นความสับสนAND-OR บางทีคุณอาจต้องการแถวทั้งหมดที่มีfromid=60และแถวทั้งหมดที่มีtoid=78และจากนั้นให้เฉพาะผู้ที่มีอย่างใดอย่างหนึ่ง's'หรือ'f'หรือt'is_approved? ถ้าใช่ลองเงื่อนไขนี้:WHERE (fromid=60 OR toid=78) AND (is_approved IN ('s', 'f', 't'))
ypercubeᵀᴹ

5

MySql Explain ใช้ค่าที่คุณกำหนดตามตัวอักษรเพื่อสำรวจแถวของตารางที่เกี่ยวข้อง หากคุณระบุค่าคงที่ / คีย์ซึ่งไม่ได้อยู่ในตารางที่เกี่ยวข้อง MySql Explain จะหยุดด้วยข้อผิดพลาดนี้ เพียงค้นหาตารางที่เกี่ยวข้องเพื่อหาค่าที่มีอยู่และระบุค่าในแบบสอบถามอธิบายของคุณและทุกอย่างจะทำงานตามที่คาดไว้


3
Impossible WHERE noticed ...ไม่ใช่ข้อผิดพลาด มันเป็นส่วนหนึ่งของการอธิบาย
ypercubeᵀᴹ

3

Impossible WHERE noticed after reading const tables ในการอธิบายแบบสอบถาม?

ข้อผิดพลาดนี้เกิดขึ้นเนื่องจากมีการใส่ค่าที่ไม่ถูกต้องในคอลัมน์ซึ่งเป็นคีย์หลักหรือคีย์เฉพาะ

ลองด้วยค่าที่ถูกต้องในwhereข้อ


0

ฉันกระโดดเข้ามาสายนี้ แต่นี่คือสิ่งที่ฉันสังเกตเห็นสำหรับฉัน

ฉันกำลังทำแบบสอบถามนี้และคอลัมน์รายการเป็น UNIQUE

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

ซึ่งจะได้รับสิ่งที่เป็นไปไม่ได้ซึ่งสังเกตเห็นหลังจากอ่านตาราง const

สิ่งที่ฉันต้องทำคือเปลี่ยน "=" เป็น "ชอบ" และตอนนี้ใช้ดัชนีของฉันแล้ว

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

มันไม่ได้ใช้ดัชนีกับ=?
ypercubeᵀᴹ

ไม่บ้าพอที่มันไม่ได้เป็น ... มันเป็นเพียงการพูดแบบนี้ในการอธิบายเป็นไปไม่ได้ซึ่งสังเกตเห็นหลังจากอ่านตาราง const
RichardW11

ใช่ แต่ว่า "เป็นไปไม่ได้ที่ไหน" มักจะดี หมายความว่าแบบสอบถามไม่จำเป็นต้องอ่านเพิ่มเติมจากตารางหรือดัชนี มันช้าไหม ถ้าไม่คุณไม่ควรกังวลเลย
ypercubeᵀᴹ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.