按联接查询中的日期排序和计算

时间:2011-05-20 14:43:51

标签: mysql sql optimization sorting

我正在做一个项目,我正在跟踪网站上的用户,我记录他们在网站上的每一个点击。每当他们点击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

为了让您了解您可以在此处看到的结构: tracking database structure http://kaspergrubbe.dk/db-overview.png

所以基本上我必须通过查看上个月的visitor_resources.last_visited来计算给定月份中有多少visitor_resources,并获得5个访问量最大的资源。

如何处理?

上面的查询在没有查询缓存的情况下看起来也很慢,我怀疑是因为t.tag_name不是索引,而且是varchar,但是除了添加这个索引之外还有加速进程吗? / p>

感谢。

2 个答案:

答案 0 :(得分:1)

您已根据日期遗漏了任何条件,因此您应该添加该条件并查看效果如何变化。此外,如果您正在寻找计数,那么您也应该添加它。我认为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,所以我不知道最后一行的开始和结束日期参数是什么样的。

除非您的Tags表非常大,否则索引可能无关紧要。关于Visitor_Resources.last_visited的索引可能是一个好主意。

另外,我更改了查询中的表名以使其更加一致。我个人喜欢复数名字,但单数也可以。无论你选择哪一个,选择一个并坚持下去。

答案 1 :(得分:-1)

Kasper,

首先你需要调整你的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个条目。

希望这有帮助。