这是我的表结构:
CREATE TABLE `instagram_user_followers_mapping` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`instagram_user_id` varchar(20) NOT NULL,
`instagram_profile_id` varchar(20) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `instagram_unique_user_follower_mapping` (`instagram_user_id`,`instagram_profile_id`),
KEY `instagram_user_followers_mapping_created_at_index` (`created_at`),
KEY `instagram_user_followers_mapping_updated_at_index` (`updated_at`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPRESSED
我在这张表中有超过1亿行。当我尝试在两个或多个" instagram_user_id"之间获取常用关注者时,它适用于表中少于20,000行的配置文件。但对于行超过2mil的配置文件,它的工作速度非常慢。我想让这些数据实时显示,以便进行分析和报告。最终用户可能会选择任何配置文件组合,因此在此处创建摘要表并不是一个很好的选择。
我用来获取交集的查询是:
select instagram_profile_id, count(*) as myCount
from instagram_user_followers_mapping
where instagram_user_id IN ('1142282','346115','663620','985530')
group by instagram_profile_id HAVING myCount >= 4
答案 0 :(得分:0)
IN
条款有点特别。使用此查询可以解决您的问题。我在{where>子句中将count(*)
更改为count(id)
并将IN
语句更改为相等。
select instagram_profile_id, count(id) as myCount
from instagram_user_followers_mapping
where instagram_user_id = '1142282' or instagram_user_id = '346115' or instagram_user_id = '663620' or instagram_user_id = '985530'
group by instagram_profile_id HAVING myCount >= 4
答案 1 :(得分:0)
' IN' vs' OR'应该不是问题。查询解释器应该认为它们是相同的(EXPLAIN应该证明这一点)。
实际上,在该查询上复制和粘贴EXPLAIN非常有用......
由于这是我们在这里处理的相当多的行,因为你的索引看起来足够,我会看(2)事情。首先是整体db配置(确保足够的ram到innodb_buffer_pool等)。第二个(也是更可能的)问题是GROUP BY非常慢。尝试增加排序缓冲区类型参数,并在这里查看更多想法: https://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html
另外,如果可以,请尝试运行每个' WHERE instagram_user_id ='作为单独的查询。
一般来说,这不是MySQL快速恶作剧的事情,但通过一些工作,你可以让它为你工作。您可能需要在应用程序方面获得一些创意,具体取决于您需要多快的速度。
答案 2 :(得分:0)
这应该运行得更快,但需要构建查询:
select instagram_profile_id
from instagram_user_followers_mapping AS t
WHERE instagram_user_id = '1142282'
AND EXISTS
(
SELECT *
FROM instagram_user_followers_mapping
WHERE instagram_profile_id = t.instagram_profile_id
AND instagram_user_id = '346115'
)
AND EXISTS
(
SELECT *
FROM instagram_user_followers_mapping
WHERE instagram_profile_id = t.instagram_profile_id
AND instagram_user_id = '663620'
)
AND EXISTS
(
SELECT *
FROM instagram_user_followers_mapping
WHERE instagram_profile_id = t.instagram_profile_id
AND instagram_user_id = '985530'
);
此公式避免了文件排序,并避免收集给定profile_id的所有user_id(反之亦然)。
innodb_buffer_pool_size
是否大于索引大小?