我正在做一个项目,我正在跟踪网站上的用户,我记录他们在网站上的每一个点击。每当他们点击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>
感谢。
答案 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个条目。
希望这有帮助。