我正在跟踪用户访问我们网站上的课程页面。我这样做,以便对于任何给定的课程(又名产品),我可以提取用户访问过的其他顶级课程页面的列表,他们也访问了当前页面 - 就像亚马逊的“观看此项目的客户一样”特征
我所拥有的是工作,但随着收集的数据不断增长,查询时间变得越来越慢。我现在有大约300k的记录,查询每次需要2秒以上。当我们达到大约2M的记录时,我们期望开始修剪数据,但鉴于我们目前面临的性能问题,我认为这不可行。我想知道是否有更好的方法来解决这个问题。
这是血淋淋的细节...
我有一个简单的三列InnoDB表,其中包含用户ID,课程编号和时间戳。用户ID和课程编号字段被编入索引,用户ID /课程编号组合在一起。这是表模式:
CREATE TABLE IF NOT EXISTS `coursetracker` (
`user` varchar(38) NOT NULL COMMENT 'user guid',
`course` char(8) NOT NULL COMMENT 'subject code and course number',
`visited` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'last visited time',
UNIQUE KEY `ndx_user_course` (`user`,`course`),
KEY `ndx_user` (`user`),
KEY `ndx_course` (`course`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='tracking user visits to courses';
表中的数据如下所示:
user | course | visited
=======================================|==========|====================
{00001A4C-1DE0-C4FB-0770-A758A167B97E} | OFFC2000 | 2013-01-19 23:18:03
{00001FB0-179E-1E28-F499-65451E5C1465} | FSCT8481 | 2013-01-30 13:12:29
{0000582C-5959-EF2B-0637-B5326A504F95} | COMP1409 | 2013-01-13 16:09:42
{0000582C-5959-EF2B-0637-B5326A504F95} | COMP2051 | 2013-01-13 16:20:41
{0000582C-5959-EF2B-0637-B5326A504F95} | COMP2870 | 2013-01-13 16:25:41
{0000582C-5959-EF2B-0637-B5326A504F95} | COMP2920 | 2013-01-13 16:24:40
{00012C64-2CA1-66DD-5DDC-B3714BFC91C3} | COMM0005 | 2013-02-18 21:32:36
{00012C64-2CA1-66DD-5DDC-B3714BFC91C3} | COMM0029 | 2013-02-18 21:34:04
{00012C64-2CA1-66DD-5DDC-B3714BFC91C3} | COMM0030 | 2013-02-18 21:34:50
{00019F46-6664-28DD-BCCD-FA6810B4EBB8} | COMP1409 | 2013-01-16 15:48:49
我用来获取任何给定课程(本例中为COMP1409)的相关课程的示例查询如下所示:
SELECT `course`,
count(`course`) c
FROM `coursetracker`
WHERE `user` IN
(SELECT `user`
FROM `coursetracker`
WHERE `course` = 'COMP1409')
AND `course` != 'COMP1409'
GROUP BY `course`
ORDER BY c DESC LIMIT 10
此查询的结果如下所示:
course | c
=========|====
COMP1451 | 470
COMP1002 | 367
COMP2613 | 194
COMP1850 | 158
COMP1630 | 156
COMP2617 | 126
COMP2831 | 119
COMP2614 | 95
COMP1911 | 79
COMP1288 | 76
所以,除了表演之外,上面的所有内容都与我想的完全一样。该表非常简单,没有任何内容可供索引。 SQL查询会生成我正在寻找的数据。我对如何更快地做到这一点没有想法。我很感激有关这种方法的任何反馈。
答案 0 :(得分:1)
您可以尝试使用联接:
SELECT c1.`course`,
count(c1.`course`) as c
FROM `coursetracker` c1
INNER JOIN `coursetracker` c2
ON c1.`user` = c2.`user`
WHERE c2.`course` = 'COMP1409'
AND c1.`course` != 'COMP1409'
GROUP BY c1.`course`
ORDER BY c DESC LIMIT 10
答案 1 :(得分:0)
SELECT `course`, count(`course`) c
FROM `coursetracker` c
INNER JOIN `coursetracker` c2 ON c.user = c2.user
WHERE c2.`course` = 'COMP1409'
AND c.`course` != 'COMP1409'
GROUP BY `course`
ORDER BY c DESC LIMIT 10