За последние 24 часа нас посетили 21472 программиста и 1667 роботов. Сейчас ищут 700 программистов ...

Запрос без "GROUP BY" или как его оптимизировать?

Тема в разделе "MySQL", создана пользователем Riddick, 19 окт 2010.

  1. Riddick

    Riddick Активный пользователь

    С нами с:
    13 июн 2008
    Сообщения:
    80
    Симпатии:
    0
    Адрес:
    Россия
    Добрый день. Есть запрос в базу данных вида:

    [sql]SELECT count(*) FROM `apache_log` WHERE id_date = 122[/sql](0.0007 сек.)

    Он выводит количество IP-адресов, за дату id_date.

    Небольшое пояснение к таблицам.
    apache_log.is_page => BOOLEAN
    apache_log.id_date => INT (проиндексировано и связано с dates.id_date)
    dates.id_date => INT (первичный ключ)
    dates.date => DATE(уникальный индекс)

    Необходимо его привести к виду:

    [sql]
    SELECT COUNT(*)
    FROM apache_log
    WHERE id_date
    IN (
    SELECT id_date
    FROM dates
    ORDER BY date DESC
    )
    GROUP BY id_date
    LIMIT 10 [/sql]
    (0.0173 сек.)

    GROUP BY очень сильно тормозит запрос(без него тоже 0,0006 приблизительно уходит на запрос, но результат не тот что нужен)). Подскажите пожалуйста каким образом можно сделать запрос быстрым, как быть с GROUP BY? Как его индексируют, либо обходятся без него? Желательно на моем примере.

    P.S.: в IN запросе у нас выделяется сразу вся таблица с dates, на моем примере она весит не много и проиндексирована хорошо, но в идеале нужно же брать 10 записей? Опять же LIMIT 10 не работает во вложенном запросе.

    Надеюсь достаточно сведений дал о структуре базы данных.

    Если бы разобрался с этим запросом жизнь на время стала бы прекрасней. Всем спасибо большое, надеюсь на вашу помощь.
     
  2. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Riddick
    А обязательно IN ? Неужели для случая с датами нельзя сформировать условие типа WHERE id_date>...?
     
  3. Riddick

    Riddick Активный пользователь

    С нами с:
    13 июн 2008
    Сообщения:
    80
    Симпатии:
    0
    Адрес:
    Россия
    В случае с датами и формированием условия WHERE id_date > у меня все равно запрос получился дольше.

    А если сделать вывод 10 дат из проиндексированной таблицы, а потом в цикле php вывести по одной(LIMIT 1) 10 строк с COUNT(*)?

    [sql]SELECT count(*) FROM `apache_log` WHERE id_date = 122[/sql]
    (0.0007 сек.)

    Просто вычитал когда гуглил что MySQL оперирует множествами, и ни в коем случае нельзя делать запросы в циклах. Хорошо, но в моем случае получается быстрее так: ~0,0005 скорость одного запроса * 10 и еще ~0,0005 на вывод дат итого = 0,0055 - это конечно только на работу MySQL уйдет, но ведь быстрее!
     
  4. Riddick

    Riddick Активный пользователь

    С нами с:
    13 июн 2008
    Сообщения:
    80
    Симпатии:
    0
    Адрес:
    Россия
    Вот это меня устроило:
    [sql]SELECT date, COUNT( * )
    FROM apache_log
    GROUP BY date
    ORDER BY date DESC
    LIMIT 10
    [/sql]
    (0.0099 сек.)

    Не буду изобретать велосипеды...

    P.S.: Занес дату обратно в таблицу apache_log, т.е. теперь date вместо id_date. Денормализация вроде это называется...