Чому я отримую "Неможливо, де БЕ помічено після читання таблиць const" у запиті пояснення?


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 прочитав усі constsystem) таблиці і зауважив, що WHEREстаття завжди хибна

const таблиці визначаються як

У таблиці є щонайбільше один відповідний рядок, який читається на початку запиту. ... constвикористовується при порівнянні всіх частин а 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але не обов'язково однакові рядки?
Мартін Сміт

1
Можливо, це AND-ORплутанина . Можливо, ви хочете, щоб усі рядки, які мають, fromid=60і всі рядки, які мають, toid=78а потім із цих, зберегли лише ті, які мають або затверджено, 's'або 'f'або t'підтверджено? Якщо так, спробуйте виконати цю умову: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

Я стрибаю в це пізно. Але ось що я помітив для мене.

Я робив цей запит, і стовпець елемента був УНІКАЛЬНИМ.

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ᵀᴹ

Ніякого божевільного, це не було .... Це було просто
сказане

Так, але те, що "неможливо ДЕЙ", як правило, добре. означає, що запит більше не повинен читати з таблиць або індексів. Це було повільно? Якщо ні, то зовсім не варто хвилюватися.
ypercubeᵀᴹ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.