При сравнении дат база жутко тормозит

Droniuz

Guest
При сравнении дат база жутко тормозит

Столкнулся с проблемой. При сравнении дат база начинает просто умирать.

По порядку. Есть таблица count с полем hitdate (тип DATETIME) - в нее вносятся посещения сайта. Загрузили сайт - запись в базу внеслась. Ну типа простейший счетчик. Таких записей в базе уже около 500000.

Надо теперь получить кол-во посещений за каждый день. Делаю так:

// получаем кол-во прошедших дней с определенного числа
$query = "SELECT TO_DAYS(NOW()) - TO_DAYS('2005-01-01') AS total";
$getAll = mysql_query($query, $base) or die(mysql_error());
$row_getAll = mysql_fetch_assoc($getAll);
$all_days = $row_getAll['total'];
// и в цикле перебираем дни
for ($i=0; $i<=$all_days; $i++) {
// считаем все загрузки в этот день
$query = "SELECT COUNT(*) AS total FROM counter WHERE DAYOFYEAR(counter.hitdate)=DAYOFYEAR(DATE_ADD('2005-01-01', INTERVAL $i DAY))";
$getAll = mysql_query($query, $base) or die(mysql_error());
$row_getAll = mysql_fetch_assoc($getAll);
$all_loads = $row_getAll['total'];
echo $all_loads."<br>";
}

Вот эта конструкция обсчитывается минутами. Неужели так сложно MySQL'ю посчитать и сравнить даты.

Пробовал ставить индекс на поле hitdate, но кажется это бессмысленно, так как все значения уникальны. Кароче индексация бесполезна в этом случае.

Просветите пожалуйста, неужели это я такую неоптимальную схему придумал? Может есть более простое и элегантное решение?
 

Bambuk

Новичок
Всё можно получить одним запросом, достаточно применить группировку.
SELECT COUNT(*) AS total FROM counter WHERE counter.hitdate > '2005-01-01'
GROUP BY counter.hitdate
 

camka

не самка
where hitdate = curdate();

и индекс на hitdate

А ты сравниваешь не индексированное значение, а функцию от него. Вот потому то индекс тебе и не помогает.

Bambuk
group by ne nado
 

Кром

Новичок
camka по-моему, ты ошибаешся. Bambuk написал правильный запрос. Только там надо отформатировать дату в DATE из DATETIME.

...GROUP BY date_format(`hitdate`,"%Y-%m-%d")
 

camka

не самка
Каюсь, грешен. Как обычно не до конца вник в суть вопроса.

А насчет GROUP BY DATE_FORMAT(...), я бы такого не стал делать, поскольку появляется using filesort и using temporary.
Одним из выходов может быть отказ от DATETIME тима, если он действительно не нужен и перевод его в DATE.
Второй вариант - создание дополнительного поля типа DATE и работа с ним.

Всё-таки на пол миллиона записей это будет ощутимый выйгрыш.
 

Droniuz

Guest
Спасибо, сделал так:

SELECT COUNT(*) AS total FROM counter GROUP BY DATE_FORMAT(counter.hitdate,"%Y-%m-%d")
 

Falc

Новичок
DATE_FORMAT универсальная функция и поэтому не очень быстрая. Использование ее в групировке особено на больших объемах групируемых данных будет весьма медлено. Я бы рекомендовал использовать вместо нее TO_DAYS.
 
Сверху