不同的计数指数 - MYSQL

时间:2013-10-25 16:37:08

标签: mysql sql optimization

我有简单的表(MYSQL - MyISAM):

编辑:这是一个50M的记录表,添加一个新索引并不是我们能做的事情。

actions (PRIMARY action_id, user_id, item_id, created_at)

Indicies:

action_id (action_id, PRIMARY)
user (user_id)
item_user (user_id, item)
created_user (user_id, created_at)

查询:

SELECT count(distinct item_id) as c_c from actions where user_id = 1

解释:

 1  SIMPLE  action  ref user_id,created_user    user_id 4   const   1415    

对于超过1k条目的用户,此查询大约需要7秒钟。有什么方法可以改善吗?

我尝试了以下内容,但情况更糟:

SELECT count(*) from actions where user_id =1 group by item_id
SELECT count(item_id) from actions USE INDEX (item_user) where user_id = 1 group by item_Id 

2 个答案:

答案 0 :(得分:0)

您可以测试以下内容:

SELECT count(*) as c_c 
   from (
       SELECT distinct item_id 
       from actions where user_id = 1
        ) as T1

答案 1 :(得分:0)

如果您使用的是PHP,可以将查询简化为以下内容:

SELECT distinct item_id 
FROM actions 
WHERE user_id = 1

然后使用mysql_num_rows获取结果中的行数?

您可以尝试的其他选项,虽然需要更多工作,但是:

1- 创建另一个表,其中包含为每个user_id找到的总行数。这意味着你必须创建一个包含两列的表,一列是user_id,第二列是你上一张表中找到的total项。

2- 安排作业运行,例如每1小时运行一次,并使用'actions`表返回的总计更新表。此时,您可以像这样查询新创建的表:

SELECT total
FROM actions_total
WHERE user_id = 1

当你需要最终结果时,这会快得多,因为你处理的是一行而不是数千行。这里的缺点是,根据您的工作需要,您可能无法获得准确的结果。

3-如果您决定不使用工作。您实际上仍然可以使用新创建的表,但每次插入/删除到“actions”表时,您都需要更新(递增/递减)它的总数。

N.B:试着帮忙