mysql - Mysql count() 与 Left Join 在 500 万条记录上花费超过 10 秒
问题描述
我有以下两个表,我正在像这样加入我正在使用 mysql v. 5.7
表:联系人约 500 万
id : auto inc (int) 主键
状态:Int(索引)
表:contact_lists约 1000 万
id : auto inc (int) 主键
联系人 ID:索引
listId:索引
表:列出大约 30 个
id: auto inc (int) 主键
这是我的查询,我在联系人表上有 1000 万条记录
SELECT cl.listId, count(c.id) active from `contact_lists` cl
LEFT JOIN `contacts` c ON c.id = cl.contactId and c.status = 1
group by cl.listId
这是我的解释
1 SIMPLE cl NULL listId contact_lists 8 NULL 9062524 100.00 Using index
1 SIMPLE c NULL eq_ref PRIMARY PRIMARY 4 cl.contactId 1 100.00 Using where
当我运行这个查询时,它需要超过 11 秒,知道如何加快它
我已经尝试添加索引,但没有任何效果,我可以以某种方式重写它以使其更快吗?不到 2 秒,问题是当涉及到这么多数据时,count(c.id) 非常慢
结果
listId. active
1 100
2. 3000
3. 500010
and so on
解决方案
根据您的Explain
结果,没有 id 和 status 的索引。创建那些:
ALTER TABLE `contact`
ADD INDEX `id_status` (`id`, `status`);
而且你还需要一个关于contact_list的外键:
ALTER TABLE `contact_list`
ADD CONSTRAINT `FK_contact_list_contact` FOREIGN KEY (`contactId`) REFERENCES `contact` (`id`);
请注意,进行这些更改可能会锁定您的表一段时间
推荐阅读
- python - 有人能告诉我以下两种在 Python3 中遍历和修改列表的方法之间的区别吗?
- javascript - 为什么函数参数被“转换”为数组
- python-3.x - 给定变量的数组符合形状
- html - 如何将功能正常的 HTML 程序导入 Bootstrap 项目?
- python - Html 中的烧瓶 Python 函数
- android - Android 浏览器看不到 Fiddler 代理
- r - 用于获取目录中子目录(即文件夹)大小的 R 脚本?
- rxjs - RxJS 中的 tap 和 map 有什么区别?
- php - 为什么我不能使用 Vue 初始化 Channel?
- docker - azuredevops docker build 在构建后处理文件时失败