Neden "Const tabloları okuduktan sonra NEREDE fark edilmiyor?" Sorgusunu açıklıyor muyum?


27

Tablodaki fr (fromid, toid) gibi benzersiz bir bileşik anahtarım var, sorguyu açıkladığımda aşağıdaki sonucu alıyorum:

Impossible WHERE noticed after reading const tables`

Çalıştırdığım sorgu:

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

Herhangi bir yardım?

EDIT1:
Aşağıdaki sorguyu kullandığımda:

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Önceki ileti yerine görüyorum , ancak aşağıdaki sorguyu kullandığımda:

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

Yine ilk impossible ...mesajı alıyorum! Bu parantezlerin burada ne işi var?

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 sitesinde söylediği gibi:

İmkansız NEDEN const tabloları okuduktan sonra fark

MySQL tüm const (ve system) tablolarını okudu ve WHERE yan tümcesinin her zaman yanlış olduğunu fark etti.

Ancak sorguda istediğim sonucu alıyorum, WHEREkısmı değil false. Bunu açıklayabilecek ve konuyla ilgili biraz ışık tutabilecek biri var mı?


Ne SELECT COUNT(1) FROM relationship WHERE fromid=78 AND toid=60;geri döner ???
RolandoMySQLDBA

@RolandoMySQLDBA, using indexyerine ekstra olacakimpossible...
ALH

Yanıtlar:


23

Mesajı alıyorsun

İmkansız NEDEN const tabloları okuduktan sonra fark

Bu, daha önce bağladığınız sayfada belgelenmiştir .

MySQL tüm const(ve system) tabloları okudu ve WHEREfıkranın her zaman yanlış olduğunu fark etti.

const tablolar

Tabloda, sorgunun başında okunan en fazla bir eşleşen satır vardır. ... consta PRIMARY KEYveya UNIQUE dizinin tüm bölümlerini sabit değerlerle karşılaştırdığınızda kullanılır .

Bir var UNIQUE KEYAÇIK (fromid,toid). Sorgu WHERE fromid=78 AND toid=60bu benzersiz dizini okuyarak sağlanabilir. Aldığınız mesajdan sonuç alınmamalı.

Benzer şekilde, sorgu WHERE fromid=60 and toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')bu dizini, ilgilenilen satırı bulmak için de kullanabilir (yine de değerlendirmek için kalan bir tahmin olmasına rağmen, eşleşecek herhangi bir satır vardı).

Diğer sorgunuz farklı

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

ANDolandan daha yüksek önceliğe sahip Or, bu nedenle

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

Bu, artık bu dizini kullanamaz ve diğer sütunlardaki değerlerin ne olduğuna bakılmaksızın herhangi bir satır döndürecek şekilde farklı bir anlam ifade eder is_approved IN ('f','t').


Peki nasıl mesela demeliyim: onun eğer fromid=12 AND toid=78o olmadığını kontrol is_approved='f'veya is_approved='t'veyais_approved='s'
ALH

1
@ john.locke: Bu üçüncü sorgunuz: WHERE fromid=60 AND toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')ki şu şekilde de yazılabilir:WHERE fromid=60 AND toid=78 AND ( is_approved IN ('s', 'f', 't') )
ypercubeᵀᴹ

1
Kesinlikle. Çünkü hiçbir satır fromid=60 AND toid=78parçaya uymuyor, bu yüzden daha fazla kontrol gerekmiyor ( is_approvedparça için).
ypercubeᵀᴹ

1
Sen satır olamaz s do. Benzersiz bir kısıtlama var, (fromid,toid)bu yüzden kesinlikle bir tane olacak? Ve söylediğiniz mesajdan MySQL aldığınızı söyleyenlerin bile olduğunu sanmıyor. Eşleşen bazı satırların ve eşleşen fromid=60bazı satırların toid=78ancak aynı satırların olmadığını mı kastediyorsunuz ?
Martin Smith,

1
Belki de bu AND-ORkarışıklıktır . Belki sahip olan tüm satırları ve sahip olan fromid=60tüm satırları toid=78ve onlardan gelenleri istersiniz , sadece ya da 's'ya 'f'da t'is_approved olanları saklayın? Eğer evet ise, bu koşulu deneyin:WHERE (fromid=60 OR toid=78) AND (is_approved IN ('s', 'f', 't'))
ypercubeᵀᴹ

5

MySql Explain, sağladığınız değerleri, ilişkili tabloların satırlarını geçmek için kullanır. İlgili tabloda olmayan bir sabit / anahtar değeri sağlarsanız, MySql Explain bu hatayı durduracaktır. Basitçe var olan değerleri açıklamak için ilgili tabloları sorgula ve Açıkla sorgunuzda bu değerleri sağlayın; her şey beklendiği gibi çalışacaktır.


3
Impossible WHERE noticed ...bir hata değil. Açıklamanın bir parçası.
ypercubeᵀᴹ

3

Impossible WHERE noticed after reading const tables sorguda açıklamak?

Bu hata, geçersiz anahtarın birincil anahtar veya benzersiz anahtar olan bir sütuna konması nedeniyle oluşur.

Yan wheretümce doğru bir değerle deneyin .


0

Bu geç içine atlıyorum. Ama işte benim için farkettim.

Bu sorguyu yapıyordum ve madde sütunu UNIQUE idi.

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

const tablolarını okuduktan sonra Impossible NEREDE fark edilmesini sağlayacaktır

Tek yapmam gereken "=" ifadesini "beğen" olarak değiştirmekti ve şimdi dizimi kullanıyor.

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

Dizini ile kullanmıyor muydu =?
ypercubeᵀᴹ

Yeterince çılgınca değildi .... Sadece şunu açıklıyordu açıklamasında imkansız
NEDEN

Evet, ama bu "imkansız NEREDE" genellikle iyidir. Sorgunun tablolardan veya dizinlerden daha fazla okumak zorunda olmadığı anlamına gelir. Yavaş mıydı Olmazsa, hiç endişelenmemelisin.
ypercubeᵀᴹ
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.