Я работаю над приложением laravel 4.2, которое работало на MySQL 5.5. Это приложение перенесено на новый сервер, на котором запущена MySQL 5.7.
После обновления некоторые запросы теперь возвращаются пустыми.
Я считаю, что это связано с введением sql_mode в mysql 5.7.
Пример запроса
SELECT * FROM `table1` WHERE `col1` = 'val1' and
(SELECT count(*) FROM `table2`
WHERE `table2`.`table1_id` = `table1`.`id`
and `driver_id` = '39') >= 1 and `table1`.`id` = '86' LIMIT 1
Это запрос, который производит laravel eloquent. Возвращается пустым. На старом mysql 5.5 он возвращает одну строку, как и ожидалось.
Если исправлен идентификатор из основного запроса, он работает.
... WHERE `table2`.`table1_id` = 86 ...
Как я уже говорил, я считаю, что это как-то связано с sql_mode.
Какие-нибудь мысли?
В запросе нет ничего плохого, это правда, что вы можете изменить запрос, чтобы избежать проблемы, но это не решает реальную проблему.
Решение состоит в том, чтобы отключить index_merge_intersection в optimizer_switch конфигурации.
Это ошибка, найденная в MySQL 5.7
https://bugs.mysql.com/bug.php?id=79675
Это сработало для меня.
В большинстве баз данных, которые его поддерживают, count(*)
на самом деле не получает все записи и не считает их — вместо этого он выбирает поле метаданных, которое просто отслеживает количество строк
Конечно, разумно ожидать, что, независимо от того, как это реализовано, результат count(*)
будет такой же, как более сложный, но эквивалентный запрос.
SELECT * FROM `table1` WHERE `col1` = 'val1' and
(SELECT count(`table2`.`id`) FROM `table2`
WHERE `table2`.`table1_id` = `table1`.`id`
and `driver_id` = '39') >= 1 and `table1`.`id` = '86' LIMIT 1
или для получения логического значения попробуйте это
SELECT * FROM `table1` WHERE `col1` = 'val1' and
(SELECT 1 FROM `table2`
WHERE `table2`.`table1_id` = `table1`.`id`
and `driver_id` = '39') >= 1 and `table1`.`id` = '86' LIMIT 1