2011-12-26 7 views
2

Я делаю два запросаИндекс MySQL проблема при работе с функцией

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

и

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

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

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

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

+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+ 
| 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(), занимает гораздо больше времени, используя функцию, чем давать ее прямо.

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

+1

Затрудняюсь ответить, не зная, что 'getNow()' делает, не так ли? –

+0

Извините. getNow() просто выполните RETURN NOW(); – Spredzy

+1

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

ответ

3

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

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

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

SELECT * 
FROM datedim 
JOIN (SELECT YEAR(getNow()) as `year`) as y 
USING (`year`); 
0

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

0

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

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