MySQL - 帮助进行高效的查询

时间:2013-03-28 15:12:40

标签: mysql performance greatest-n-per-group

我有一张表,我将所有登录信息存储到我的网站。结构如下:

TABLE users_logins

loginid INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
userid INT
iplogin VARCHAR(15)
logindate datetime

现在,我需要一个查询来检索使用相同IP进行FIRST登录的用户数。结果应该是这样的:

iplogin | numberofaccounts

正如我之前所说,'numberofaccounts'是首次使用相同'iplogin'登录的用户数。

这张桌子有大约300k排...所以我应该做些什么来获得我需要的好表现呢?

谢谢,

L,

2 个答案:

答案 0 :(得分:0)

我只是在用户表中为第一个登录ip添加一列。然后这是一个简单的

select count(*), firstip 
from users 
group by firstip

答案 1 :(得分:0)

添加以下索引:

alter table users_logins 
  add key (iplogin, userid, logindate),
  add key (userid, logindate);

现在演示您可以通过查找同一用户没有其他早期登录的登录信息来执行查询以获取每个用户的最早登录信息。

这是获得每位用户或其他任何人最大/最早条目的常见解决方案。

select t1.iplogin, count(*) as numberofaccounts 
from users_logins as t1 
left outer join users_logins as t2 
  on (t1.userid=t2.userid and t1.logindate > t2.logindate) 
where t2.userid is null 
group by iplogin\G

上面定义的索引有助于LEFT OUTER JOINGROUP BY

EXPLAIN报告显示这是非常优化的。它使用两个表的索引,并且不会导致临时表或文件排序,这些都是性能杀手。

它确实进行了索引扫描(type: index),这意味着它会读取整个索引,但至少不是表扫描。

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
   partitions: NULL
         type: index
possible_keys: iplogin
          key: iplogin
      key_len: 29
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using index
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: t2
   partitions: NULL
         type: ref
possible_keys: userid
          key: userid
      key_len: 5
          ref: test.t1.userid
         rows: 1
     filtered: 100.00
        Extra: Using where