MYSQL在大表上的效率低下

时间:2015-03-03 19:38:17

标签: php mysql

我有一个具有这种结构的表:

id(int), aff_id(int)

字段aff_id0,如果用户没有任何人关联并且他直接注册,或larger than 0,如果该用户是其他玩家的附属关系,那么它需要user #47 was affiliated by user #55, therefore in the database, we will have this entry: id=47,aff_id=55 联盟会员身份证的价值。

aff_id > 0

我想看看有多少用户做得很好并且关联/带来了其他用户(基本上我想看看有多少用户是关联企业)。为此,我需要遍历每个用户,看看是否有任何人在aff_id字段中有他的用户ID。 我不想看到有多少用户SELECT COUNT(*), (SELECT COUNT(*) FROM `users` WHERE `aff_id`=`u`.`id` ) AS total_pl FROM `users` u HAVING total_pl>0 ,因为这是基本的东西,这意味着有多少玩家加入。

根据我的要求,我运行此查询:

SELECT 
  COUNT(*) 
FROM `users` u 
WHERE u.id IN (
  SELECT DISTINCT (`aff_id`) 
  FROM users 
  WHERE aff_id<>0
)

问题是在具有2000个条目的数据库上查询大约需要30秒。

如果我尝试不同的方式,则需要更多时间......大约40秒:

{{1}}

您建议我尝试进行优化还有哪些其他选择?

我正在考虑修改第一个查询以停止计算每个用户拥有多少联盟玩家,并且仅在每个用户拥有0个附属玩家或至少1个附属玩家时查找,但似乎没有任何区别

3 个答案:

答案 0 :(得分:2)

那是怎么回事:

SQL Fiddle

MySQL 5.5.32架构设置

CREATE TABLE users
    (`id` int, `aff_id` int)
;

INSERT INTO users
    (`id`, `aff_id`)
VALUES
    (47, 55),
    (48, 0),
    (49, 55),
    (50, 56),
    (51, 56),
    (53, 57)
;

查询1

SELECT COUNT(distinct aff_id)
FROM users
WHERE aff_id <> 0

<强> Results

| COUNT(DISTINCT AFF_ID) |
|------------------------|
|                      3 |

这将为您提供您所要求的内容

“我想看看有多少用户做得很好,并且加入/吸引了其他用户(基本上我想知道有多少用户是关联企业)”

答案 1 :(得分:2)

获取每个联盟会员的用户数

看起来你根本不需要使用id。为什么不呢

SELECT aff_id, count(*) FROM users
WHERE aff_id <> 0 
GROUP BY aff_id

如果这不是您的意思,请更好地解释自己。

答案 2 :(得分:0)

SELECT 
  u.id,
  COUNT(aff.id) as aff_num
FROM `users` u 
LEFT JOIN `users` aff 
ON u.id = aff.aff_id
GROUP BY u.id
ORDER BY aff_num DESC
HAVING aff_num>0

这是sqlfiddle在65条记录上执行查询需要2ms-5ms。

你可以玩更多。我很确定,即使您的表格没有正确编入索引,使用2000条记录也不会超过3秒。

所以我认为我的查询非常快,我有证据。

你有你的吗?