Как отмечено в комментарии ниже, этот ответ не решает проблему устранения неполадок в Hibernate, но ОП все равно понравился.
Ответ следует ...
Запросдля любой функции, хранимой или встроенной, всегда выполняется сканирование таблицы.
Например, при этом невозможно будет использовать индекс для create_date
, даже если он существует:
SELECT * FROM MyTable WHERE MONTH(create_date) = 2
То же самое верно всякий раз, когда вы используете индексированный столбец в качестве аргументов функции.
Обходной путь для MySQL 5.7 и более поздних версий заключается в использовании сгенерированного столбца для этого выражения,и затем индексируйте сгенерированный столбец.
ALTER TABLE MyTable
ADD COLUMN created_month INT AS (MONTH(create_date)),
ADD INDEX (created_month);
Как только вы это сделаете, вы можете запросить created_month = 2
или даже запросить исходное выражение MONTH(create_date) = 2
, и он будет использовать индекс.
К сожалению, вы можете использовать эту функцию только со встроенными функциями MySQL.
https://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.html говорит:
Сгенерированные выражения столбцов должны соответствовать следующим правилам.Ошибка возникает, если выражение содержит запрещенные конструкции.
- Сохраненные функции и пользовательские функции недопустимы.
Альтернативное решение будет для вассоздайте новый конкретный столбец для хранения результата сохраненной функции, предполагая, что значение является детерминированным по своим аргументам и не зависит от состояния данных в других таблицах.
ALTER TABLE MyTable
ADD COLUMN myAttribute INT,
ADD INDEX (myAttribute);
CREATE TRIGGER att_ins BEFORE INSERT ON MyTable
FOR EACH ROW SET NEW.myAttribute = MyFunction(NEW.attr1, NEW.attr2);
CREATE TRIGGER att_upd BEFORE UPDATE ON MyTable
FOR EACH ROW SET NEW.myAttribute = MyFunction(NEW.attr1, NEW.attr2);
Затем вы бы запросилиНовый столбец вместо выражения.
Это немного хлопотно, но это единственный способ получить индексированный поиск по результату сохраненной функции.