Как оптимизировать mysql date_format () для скорости в предложении где? - PullRequest
5 голосов
/ 19 августа 2009

Я пытаюсь оптимизировать относительно большую таблицу mysql (myisam) с 220 000 строк. Сам стол не такой большой - около 23,5 МБ. Итак, в чем реальная проблема? - я получил запрос, как это:

SELECT * FROM table WHERE DATE_FORMAT(date_field, '%m%d') = '1128' LIMIT 10

Я пытался установить индекс для поля date_field, но EXPLAIN показывает, что индекс вообще не использовался ... я думаю, это не так странно из-за DATE_FORMAT (). Итак, я планирую добавить еще один столбец, который будет содержать даты как «% m% d», и поместить в него индекс. Единственная причина, по которой я не хочу этого делать, заключается в дублировании данных.
Кстати, я использую поле date_field - поле даты рождения, и я уверен, что мне всегда нужно поле date_ как% Y-% m-% d или просто% m% d

У вас есть лучшее предложение о том, как оптимизировать запрос выше? Заранее спасибо !!!

Некоторая информация:

Версия MySQL: 5.0.51b-log
ОС: slackware 12.1
Процессор: Pentium III (Coppermine) при 996,783 МГц
Оперативная память: 512 МБ DDR
Жесткий диск: 80 ГБ SATA

P.S Я попытался добавить еще один столбец, содержащий даты как% m% d. Результаты очень хорошие, но мне все еще не нравится этот подход. Я жду больше предложений!

1 Ответ

2 голосов
/ 19 августа 2009

Если вам всегда нужен подстановочный знак для года, как, например, ваш запрос, я не уверен, что mysql сможет использовать индекс для поля даты / даты / времени

Если это только даты, вы можете создать таблицу time_dimension и предварительно заполнить ее календарем на следующие несколько лет. У меня есть хранимая процедура, чтобы сделать это, если вам нужно.

create table time_dimension (
 dbdate date primary key,
 year int NOT NULL,
 month int  NOT NULL , 
 day int NOT NULL,
 KEY(year),
 KEY(month);
 KEY(day);
);

Вы бы присоединили свою таблицу больших данных к этой сравнительно небольшой таблице и отфильтровали ее поле. например

SELECT * FROM data_table d 
  inner join time_dimension t 
    on d.date_field=t.dbdate 
where t.day=28 and t.month=11 LIMIT 10

Это использует фильтрацию для небольшого time_dimension, и объединения на date_field = dbdate обычно будут использовать индексы.

...