1
SELECT a.*, u.avatar, u.name, u.surname, u.username, COUNT(a.user1) AS cnt  
FROM user_actions a,users u,following f   
WHERE a.user1=u.user_id AND
a.user1=f.follower_id AND 
f.user_id=159 
GROUP BY a.user1, a.action, day(a.dt) 
ORDER BY a.id DESC 
LIMIT 7;

查询耗时 4.4909 秒

表 user_actions 的索引:

Action  Keyname     Type   Unique Packed Column    Cardinality Collation
Edit    PRIMARY     BTREE  Yes    No     id        516094      A        
Edit    user1       BTREE  No     No     user1     15639       A        
Edit    user2       BTREE  No     No     user2     36863       A        
Edit    action      BTREE  No     No     action    16          A        
Edit    dt          BTREE  No     No     dt        516094      A        
Edit    group_index BTREE  No     No     user1     20643       A        


EXPLAIN SELECT a . * , u.avatar, u.name, u.surname, u.username, COUNT( a.user1 ) AS cnt
FROM user_actions a, users u, following f
WHERE a.user1 = u.user_id
AND a.user1 = f.follower_id
AND f.user_id =159
GROUP BY a.user1, a.action, day( a.dt )
ORDER BY a.id DESC
LIMIT 7 

id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE f ref user_id,follower_id,for_actions for_actions 4 const 242 使用索引;使用临时的;使用文件排序 1 SIMPLE a ref user1,group_index group_index 4 pictify_main.f.follower_id 25 1 SIMPLE u eq_ref PRIMARY PRIMARY 4 pictify_main.a.user1 1 使用 where

4

4 回答 4

0

由于格式化无法理解您的索引

但是,以下索引可以提供帮助..

user_actions(user1)
following (user_id)
users(user_id)

否则按照建议,请发布解释计划。

于 2012-10-12T11:52:12.003 回答
0

由于您正在寻找特定的“以下”用户 ID,因此我会对其进行一些反转...然后添加“STRAIGHT_JOIN”子句以告诉 MySQL 按明确列出的顺序执行

确保表索引关注的索引 (User_ID, Follower_ID) 用户 (User_ID) User_Actions (User1,Action,Dt,ID)

select STRAIGHT_JOIN
      UA.*,
      U.Avatar,
      U.Name,
      U.SurName,
      U.UserName,
      count(*) as UserActionsCount
   from
      Following F
         JOIN User_Actions UA
            on F.Follower_ID = UA.User1
            Join Users U
               on UA.User1 = U.User_ID
   where
      F.User_ID = 159
   group by
      F.Follower_ID,
      UA.Action,
      Day( UA.Dt )
   order by
      UA.ID DESC
   limit 
      7
于 2012-10-12T13:01:37.243 回答
0

非确定性 GROUP BY: SQL 检索既不在聚合函数中也不在 GROUP BY 表达式中的列,因此这些值在结果中将是不确定的。

SELECT *: 选择所有带有 * 通配符的列,如果表的架构发生变化,将导致查询的含义和行为发生变化,并可能导致查询检索到过多的数据。

不带 AS 关键字 的别名 在列或表别名中显式使用 AS 关键字,例如“tbl AS alias”,比隐式别名(例如“tbl alias”)更具可读性。

于 2012-10-12T12:37:57.450 回答
0

使用连接而不是逗号分隔的FROM从句:

SELECT a.*, u.avatar, u.name, u.surname, u.username, COUNT(a.user1) AS cnt  
FROM following f
LEFT JOIN user_actions a ON a.user1 = f.follower_id
LEFT JOIN users u ON u.user_id = a.user1
WHERE f.user_id = 159 
GROUP BY a.user1, a.action, day(a.dt) 
ORDER BY a.id DESC 
LIMIT 7;

我选择使用子句中的followingFROM作为您搜索的关键部分是基于following.user_id. 这应该会减少获取的行数,因为您要尽早缩小结果集的范围。

我推荐 a LEFT JOIN,因为即使它们与其他两个表中的任何条目都不匹配,这也会返回行following,这通常是您在这种查询中想要的结果。如果您只想要在所有 3 个表中都有数据的行,请尝试INNER JOIN改用。

于 2015-11-20T16:10:19.313 回答