MySQL объясняет аномалию

Рассмотрим следующий запрос:

select FEE_NUMBER
from CARRIER_FEE CF
left outer join CONTYPE_FEE_LIST cfl on CF.CAR_FEE_ID=cfl.CAR_FEE_ID and cfl.CONT_TYPE_ID=3
where CF.SEQ_NO = (
    select max(CF2.SEQ_NO) from CARRIER_FEE CF2 
    where CF2.FEE_NUMBER=CF.FEE_NUMBER 
    and CF2.COMPANY_ID=CF.COMPANY_ID 
    group by CF2.FEE_NUMBER) 
group by CF.CAR_FEE_ID 

На моем ноутбуке это не дает результатов. Используя точно такую ​​же (сброшенную) базу данных на моих серверах, он возвращает результаты.

Если я запускаю EXPLAIN на своем ноутбуке, я получаю это

| id | select_type        | table | type  | possible_keys                               | key                   | key_len | ref                    | rows | Extra                                        |
+----+--------------------+-------+-------+---------------------------------------------+-----------------------+---------+------------------------+------+----------------------------------------------+
|  1 | PRIMARY            | CF    | index | NULL                                        | PRIMARY               | 8       | NULL                   |  132 | Using where                                  | 
|  1 | PRIMARY            | cfl   | ref   | FK_CONTYPE_FEE_LIST_1,FK_CONTYPE_FEE_LIST_2 | FK_CONTYPE_FEE_LIST_1 | 8       | odysseyB.CF.CAR_FEE_ID |    6 |                                              | 
|  2 | DEPENDENT SUBQUERY | CF2   | ref   | FK_SURCHARGE_1                              | FK_SURCHARGE_1        | 8       | func                   |   66 | Using where; Using temporary; Using filesort | 

В то время как на всех других моих серверах он дает это (обратите внимание на разницу в столбце ref)

| id | select_type        | table | type  | possible_keys                               | key                   | key_len | ref                    | rows | Extra                                        |
+----+--------------------+-------+-------+---------------------------------------------+-----------------------+---------+------------------------+------+----------------------------------------------+
|  1 | PRIMARY            | CF    | index | NULL                                        | PRIMARY               | 8       | NULL                   |  132 | Using where                                  | 
|  1 | PRIMARY            | cfl   | ref   | FK_CONTYPE_FEE_LIST_1,FK_CONTYPE_FEE_LIST_2 | FK_CONTYPE_FEE_LIST_1 | 8       | odysseyB.CF.CAR_FEE_ID |    6 |                                              | 
|  2 | DEPENDENT SUBQUERY | CF2   | ref   | FK_SURCHARGE_1                              | FK_SURCHARGE_1        | 8       | odysseyB.CF.COMPANY_ID |   66 | Using where; Using temporary; Using filesort | 

Если я удалю либо соединение, либо подзапрос, либо последнюю группировку, я получу ожидаемые результаты.

Я предполагаю, что это проблема конфигурации, но я не видел ее раньше. Кто-нибудь знает, что может вызвать это?

Мой ноутбук работает под управлением OSX 10.6 с MySQL 5.0.41. Другой ноутбук под управлением OSX 10.5.7 и MySQL 5.0.37 работает нормально, как и серверы Linux с MySQL 5.0.27.

Может ли кто-нибудь объяснить разницу между одним планом объяснения с использованием ref = func и другим с использованием ref = odysseyB.CF.COMPANY_ID?

Спасибо.


person Damo    schedule 07.09.2009    source источник
comment
Вау! тот же набор данных? разные результаты? это довольно серьезная проблема ...   -  person Pablo Santa Cruz    schedule 07.09.2009
comment
Ага. Тот же набор данных. Разные результаты. Фигово.   -  person Damo    schedule 07.09.2009
comment
вы уверены, что это тот же набор данных? строки в вашем объяснении немного отличаются. 201 и 202 16 и 18100 и 101   -  person Rufinus    schedule 08.09.2009
comment
Я обновил планы объяснения. Один из них был вырезан / вставлен из более раннего теста набора данных.   -  person Damo    schedule 08.09.2009
comment
Вы пытались либо понизить версию ноутбука до той же версии mysql, либо обновить его до последней версии 5.0.x?   -  person Craig    schedule 16.09.2009
comment
@Craig: Да, если я обновлю свой ноутбук, он будет вести себя так, как должен. Так что я могу продолжать работать, но по-прежнему вызывает опасения, что возможны такие разные результаты.   -  person Damo    schedule 16.09.2009


Ответы (2)


На обеих машинах:

mysql> SHOW CREATE TABLE CARRIER_FEE CF;

Убедитесь, что оба типа таблицы ENGINE одинаковы.

Кроме того, поскольку вы используете OS X 10.6 на машине с ошибкой? Возможно, типы данных в этой ОС имеют другие качества, чем 10.5.x.

Похоже, у людей проблемы с совместимостью со снежным барсом. Попробуйте установить MySQL 5.4 на свой ноутбук 10.6.

http://forums.mysql.com/read.php?10,278942,278942#msg-278942

person randomx    schedule 15.09.2009

Не знаю, почему это дает разные результаты. У вас нет точно такого же дампа данных, поскольку количество строк в отчетах EXPLAIN различается. Я бы рекомендовал выполнить несколько более простых запросов, чтобы проверить свои предположения.

Также дважды проверьте, действительно ли вы выполняете один и тот же SQL-запрос на обоих серверах. Например, если вы случайно изменили левое внешнее соединение на внутреннее соединение, это может привести к тому, что весь запрос не вернет результатов.

Кстати, касательно вашего вопроса, но я решаю эти запросы типа «наибольшая строка для группы» с помощью внешнего соединения:

select FEE_NUMBER
from CARRIER_FEE CF
left outer join CARRIER_FEE CF2
  on CF.FEE_NUMBER = CF2.FEE_NUMBER and CF.COMPANY_ID = CF.COMPANY_ID 
     and CF.SEQ_NO < cf2.SEQ_NO
left outer join CONTYPE_FEE_LIST cfl 
  on CF.CAR_FEE_ID=cfl.CAR_FEE_ID and cfl.CONT_TYPE_ID=3
where CF2.SEQ_NO IS NULL 
group by CF.CAR_FEE_ID;

Этот тип решения часто намного быстрее, чем решение для коррелированных подзапросов, которое вы используете в настоящее время. Я бы не подумал, что это может изменить результат запроса, я просто предлагаю это как вариант.

person Bill Karwin    schedule 08.09.2009
comment
Спасибо. Это, безусловно, вариант. Я обновил планы объяснения. Они используют точно такой же набор данных. - person Damo; 08.09.2009