Сортировка и расчет по датам в объединенном запросе - PullRequest
0 голосов
/ 20 мая 2011

Я делаю проект, в котором я отслеживаю пользователей на веб-сайте, я регистрирую их каждое попадание на сайте.Всякий раз, когда они нажимают на URL, я создам его в базе данных и помечу тегами.

Каждый URL называется «ресурсом» в моей базе данных, и ресурс может быть помечен несколькими тегами.Посетитель подключается к ресурсам, когда они посещают URL-адрес, и когда пользователь обращается к ресурсу, я также связываю с ним дату.

Я хочу найти ресурсы с правильными тегами, чтобынапример, в этом месяце или за сегодняшний день.

Запрос, который я сейчас строю, находится здесь:

SELECT r.resource_id, r.resource_url
FROM resource r
JOIN visitor_resource vt ON vt.resource_id = r.resource_id
JOIN resource_tags rt ON rt.resource_id = vt.resource_id
JOIN tags t ON t.tag_id = rt.tag_id AND t.tag_name =  '42'
GROUP BY r.resource_id

Чтобы дать вам представление о структуре, которую вы можете увидеть здесь: отслеживание структуры базы данных http://kaspergrubbe.dk/db-overview.png

Таким образом, в основном мне придется подсчитать, сколько visitor_resources существует в данном месяце, просмотрев visitor_resources.last_visited за последний месяц, и получить 5 самых посещаемых ресурсов.

Как подойти к этому?

Вышеупомянутый запрос также кажется очень медленным без кеширования запросов, я подозреваю, что это потому, что t.tag_name не является индексом, и это varchar, но есть ли способ ускорить процесс, кроме добавления этогоindex?

Спасибо.

Ответы [ 2 ]

1 голос
/ 20 мая 2011

Вы не указали ни одного критерия на основе даты, поэтому вам нужно добавить его и посмотреть, как меняется производительность.Кроме того, если вы ищете счетчик, то вы также должны добавить это.Я думаю, что mySQL поддерживает предложение LIMIT (в отличие от TOP), поэтому добавьте его для ограничения 5 наиболее посещаемых ресурсов.Все вместе, вероятно, будет выглядеть примерно так:

SELECT
    r.resource_id,
    r.resource_url,
    COUNT(*)
FROM
    Visitor_Resources VR
INNER JOIN Resources R ON R.resource_id = VR.resource_id
INNER JOIN Resource_Tags RT ON RT.resource_id = R.resource_id
INNER JOIN Tags T ON
    T.tag_id = RT.tag_id AND
    T.tag_name = '42'
WHERE
    VR.last_visited BETWEEN <start of month> AND <end of month>
GROUP BY
    r.resource_id,
    r.resource_url
ORDER BY
    COUNT(*) DESC
LIMIT 5

Извините, я не очень много делаю с MySQL в наши дни, поэтому я не знаю, как будут выглядеть параметры начальной и конечной даты.в последней строке.

Если ваша таблица тегов не очень велика, индекс, вероятно, не будет иметь большого значения.Хотя индекс Visitor_Resources.last_visited может быть хорошей идеей.

Кроме того, я изменил имена таблиц в запросе, чтобы они были более согласованными.Лично мне нравятся множественные имена, но в единственном числе тоже нормально.Неважно, что вы выберете, выберите один и придерживайтесь его.

0 голосов
/ 20 мая 2011

Каспер,

Прежде всего, вам нужно настроить JOIN. Нет необходимости говорить «JOIN ON» в каждой строке:

ie.
        LEFT JOIN(
        groups, sign
        )ON(
        user.user_id = groups.userID AND
        groups.group_id = sign.groupID

Попробуйте что-нибудь подобное для соединений.

Затем добавьте ORDER BY в предложение.

ORDER BY last_visited DESC LIMIT 5;

Это отсортирует вашу таблицу дат и возьмет самые последние 5 записей, из которых вы когда-либо указывали столбец.

Надеюсь, это поможет.

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