#mysql
Вопрос:
В течение довольно долгого времени я писал специальные запросы к нашей базе данных, которые выглядят следующим образом:
USE db_name;
SET @entity_name = 'EntityName';
SELECT *
FROM data d JOIN entities e ON d.entity_id = e.id
WHERE e.name = @entity_name;
Это работало нормально в течение довольно долгого времени. Недавно я обнаружил, что этот запрос имеет ужасную производительность, когда запрос не возвращается. Я смог устранить проблему, переключившись на это:
USE db_name;
SELECT CONVERT('EntityName' USING LATIN1) INTO @entity_name;
SELECT *
FROM data d JOIN entities e ON d.entity_id = e.id
WHERE e.name = @entity_name;
name
Столбец имеет значение VARCHAR(45), с параметрами сортировки latin1_swedish_ci, и если я запущу:
USE db_name; SELECT @@character_set_database, @@collation_database;
Я получаю latin1, latin1_swedish_ci
Я не уверен, почему оптимизатору вдруг понадобилась подсказка о том, какого типа/сортировки должна быть переменная, чтобы найти правильный индекс.
Есть какие-нибудь идеи?
Комментарии:
1. Что — то изменилось, совпав с моментом, когда запрос перестал иметь хорошую производительность. Обновление MySQL? Изменение конфигурации? ты когда — нибудь бегал
SET NAMES latin1
? В таблице появилось больше строк? Вы изменили определение таблицы или механизм хранения?2. Переменная не является объектом базы данных, поэтому нет никакой связи между переменной и параметрами сортировки базы данных.
3. Строки были добавлены, но таблица не изменилась. В БД произошло незначительное изменение версии, но я никогда раньше не сталкивался с этой проблемой.
Ответ №1:
Похоже, это общая проблема. 'EntityName'
поступает с некоторым набором символов и параметрами сортировки, предположительно установленными в параметрах подключения или SET NAMES
.
Но тогда оптимизатор, несмотря на то , что обычно с удовольствием преобразует константу в характеристики e.name
, похоже, не делает этого при использовании переменной@.
Я рекомендую вам сообщить об ошибке с bugs.mysql.com и разместите ссылку здесь.
PS. @@character_set_database и @@collation_database не имеют отношения к делу; пожалуйста, предоставьте SHOW VARIABLES LIKE 'char%';