Проблема с индексом MySQL при работе с функцией - PullRequest
2 голосов
/ 26 декабря 2011

Я делаю два запроса

SELECT * FROM datedim WHERE year = YEAR(now());

и

SELECT * FROM datedim WHERE year = YEAR(getNow());

Здесь функция getNow () просто возвращает NOW ();

Моя проблема в том, что первый является немедленным, а второй - намного дольше. (1xx сек)

Когда я выполняю команду объяснения, я получаю это для первой (что хорошо)

+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+
| id | select_type | table   | type | possible_keys | key         | key_len | ref   | rows | Extra       |
+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+
|  1 | SIMPLE      | datedim | ref  | dd_year_idx   | dd_year_idx | 5       | const |  365 | Using where |
+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+

Но это для второго (что довольно плохо)

+----+-------------+---------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | datedim | ALL  | NULL          | NULL | NULL    | NULL | 10958 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+-------+-------------+

Может ли кто-нибудь объяснить мне, что происходит и почему выполнение одной и той же операции, поиск всей даты с годом, который совпадает с NOW (), занимает гораздо больше времени при использовании функции, чем прямая.

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

Ответы [ 3 ]

3 голосов
/ 26 декабря 2011

MySQL, кажется, выполняет функцию getNow() для каждой строки, NOW () выполняется только один раз для оператора:

NOW () возвращает постоянное время, которое указывает время, когда оператор начал выполняться. (Внутри хранимой функции или триггера NOW () возвращает время, когда функция или оператор запуска начал выполняться.) Это отличается от поведения SYSDATE (), которое возвращает точное время, в которое она выполняется.

Но вы можете изменить свой запрос на следующий, чтобы иметь тот же эффект:

SELECT *
FROM datedim
JOIN (SELECT YEAR(getNow()) as `year`) as y
USING (`year`);
0 голосов
/ 26 декабря 2011

Я предполагаю, что MySQL знает, что он может оценивать функции YEAR() и now() до некоторого постоянного значения, поэтому после оценки их (до выполнения запроса) он может использовать индекс dd_year_idx.

MySQL не может делать то же самое с вашей пользовательской функцией

0 голосов
/ 26 декабря 2011

MySQL сканирует каждый результат, чтобы найти условие где, потому что при использовании пользовательской функции mysql не использует индексы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...