INSERT SRELECT 的瓶颈在哪儿?

zjcxc 2017-09-07 03:24:27
近 3000 万的数据,分布在 128 个表,不是平均分布,最大的表记录数 140 万
表结构:
CREATE TABLE tb ( a int, b int, c int, d varchar(40), e int )
查询语句:
SELECT a, b, c, d, COUNT(DISTINCT e) FROM tb GROUP BY a, b, c, d
记录最多的表上执行耗时 2 秒
程序使用 32 个线程并行查询 128 个表,总共花费的时间不足 5 秒(线程数为 8 和 16 时也差不多,稍微多一点时间)
问题:
把 SELECT 的数据写入表, 尝试了 INSERT SELECT 和 CREATE TABLE AS SELECT
用 32 个线程需要 25 秒左右, 8个线程也要近 20 秒,性能下降非常厉害
对于最大的表,单独测试 INSERT SELECT,比仅查询多按一秒(仅查询 2 秒,INSERT SELECT 约 2.8秒)
单表测试来看, INSERT SELECT 确实降低性能,但并行查询后的总时间开销也太离谱了,求解是什么原因导致的
注:
这个数据原来是弄成128个分区的分区表, 原来以为是 INSERT SELECT 锁表而不是分区导致的,所以分成 128 个表了,结果仍然出现这种并行 INSERT SELECT 极慢的情况
另外做了另一种测试,把 SELECT 的结棍拼成 INSERT VALUES + PREPARE STATMENT + EXECUTE STATMENT,这种处理的性能与直接 SELECT 几乎相同,所以应该可以排除是写目标表的锁(也测试过 INSERT 到不同的表,仍然是极慢)
INSERT SELECT 和 直接的 SELECT 的差别应该在于锁,所以测试了 SELECT FOR UPDATE 和 LOCK IN SHARE MODE,结果发现确实加锁后也极慢,但是锁在不同的表上,所以各查询之间的锁不冲突,不应该影响有这么大,而且单独查询最大的表验证,加锁导致的发损失不大,为什么并发的情况下会这么严重?
...全文
172 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
zjcxc 2017-09-08
  • 打赏
  • 举报
回复
另外,这个测试是在服务器上霆的 --------------------------------------测试的, 服务器也没有跑其他东西
zjcxc 2017-09-08
  • 打赏
  • 举报
回复
楼上说的 IO 是那个部分的 IO ? 如果是读取时的 IO, 那么直接查询没问题,所以不是读取时的IO 如果是写入时的 IO, 则已经试过在 SELECT 生成 INSERT VALUES 语句到 变量 + PREPARE STATMENT + EXECUTE 执行来实现 INSERT + SELECT, 这种方式也没问题,效率赞同于 SELECT 另外,INSERT 的表也试过 ENGINE = MEMORY 所以应该不是 IO 瓶颈,再说了,SELECT 的数据量确实大, INSERT 的部数也不足 5000 条,这也用不上什么 IO 另外,这个测试是在服务器上霆的,这个数据导入 SQL SERVER,放到一张表中,没任何索引,直接统计 3 秒就出来了,mysql 中放单表统计要 60 多秒,所以,并行查询是有巨大性能提升的 现在需想要搞清楚 INSERT SELECT 的瓶颈并规避它
ckc 2017-09-08
  • 打赏
  • 举报
回复
这个应该是io到了瓶颈吧 如果是cpu密集计算,多线程帮助比较大 如果是io密集的处理,多线程作用就比较小了 换好的存储,还不行就用内存数据库,反正你的总数据量其实也不算大
rucypli 2017-09-07
  • 打赏
  • 举报
回复
持续关注中

56,677

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧