对于以下要求,MySQL Query应该是什么样的

时间:2015-08-20 15:23:10

标签: mysql database

我有一个visits表,其中有三列useridurldate

每天用户访问多个页面,我们会在visits表中为每次访问存储一个条目。

现在我想要一个用户(url)今天访问但不是昨天访问的userid列表。

这是我正在尝试的当前查询。

 SELECT clickid 
 FROM   visits 
 WHERE  userid='221001' 
   AND  date = '2015-08-20' 
   AND  clickid NOT IN (SELECT clickid FROM visits WHERE userid='221001' AND date = '2015-08-19')

但是这个查询需要花费太多时间。我们的表在内部查询中可能有最多0.2M行

如何让它变得简单快捷?

1 个答案:

答案 0 :(得分:0)

来自the answer
在大多数情况下,JOIN比子查询更快,并且子查询的速度非常快。

JOIN中,RDBMS可以创建一个更适合您的查询的执行计划,并且可以预测应该加载哪些数据进行处理并节省时间,这与子查询不同,它将运行所有查询和加载所有数据以进行处理。

子查询的好处在于它们比JOIN更具可读性:这就是为什么大多数新SQL用户更喜欢它们的原因;这是简单的方法;但是在性能方面,JOIN在大多数情况下都更好,即使它们也不难阅读。

所以,请尝试这个并告诉我们结果:

    select clickid  
    from   visits v1
           left join visits v2 on v1.clickid  = v2.clickid  and v2.date = '2015-08-19'
    where  v1.userid= '221001' 
      and  v1.date = '2015-08-20' 
      and  v2.clickid   is null

或使用NOT EXISTS

 SELECT v1.clickid 
 FROM   visits v1
 WHERE  v1.userid='221001' 
   AND  v1.date = '2015-08-20' 
   AND  NOT EXISTS (SELECT NULL FROM visits v2 WHERE v2.userid=v1.userid AND v2.date = '2015-08-19')

PS:如果比较的列(userid)不可为空,LEFT JOIN在MySQL上表现最佳。如果列可以为空(值可以为NULL),则NOT EXISTS的效果会更好。