前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL Cases-SQL导致CPU使用率100%处理

MySQL Cases-SQL导致CPU使用率100%处理

原创
作者头像
姚崇
修改2021-09-18 11:35:03
1K0
修改2021-09-18 11:35:03
举报

背景

事情是这样的,让我娓娓道来...

前几天客户向我咨询一条SQL,为了客户隐私屏蔽了关键字,改成自己测试环境语句

代码语言:javascript
复制
WITH tabs AS
(
SELECT ROW_NUMBER() OVER(PARTITION by O_ORDERPRIORITY ORDER BY O_TOTALPRICE DESC) as my_rowid,
o_orderkey,
O_CUSTKEY
O_TOTALPRICE from orders where O_ORDERDATE >'1998-01-01' and O_ORDERDATE<'1998-12-30'
)
update tabs set O_TOTALPRICE = O_TOTALPRICE+1 where my_rowid>1;

看到这个条SQL写法还是有问题的,我按照他的意思做了改写,我们先分析他要的语句的逻辑

按照O_ORDERPRIORITY订单属性分组,更新每组中价格不是最大的那个值,那么好,按照这个意思,我该写成如下,o_orderkey是订单表主键

代码语言:javascript
复制
update orders
set O_TOTALPRICE = O_TOTALPRICE + 1
where o_orderkey
          in
      (select o_orderkey
       from (
                SELECT ROW_NUMBER() OVER (PARTITION by O_ORDERPRIORITY ORDER BY O_TOTALPRICE DESC) as my_rowid,
                       o_orderkey
                from orders
                where O_ORDERDATE > '1998-01-01'
                  and O_ORDERDATE < '1998-12-30'
            ) x
       where x.my_rowid > 1
      );

我提醒MySQL中批量更新要分批执行

CPU100%

又过了几天客户,说CPU 100%了,查询慢SQL正式,前几天那个关联更新...

那么这个SQL为什么这么慢呢...先说下Oracle中的解决办法,可以改写成merge into引导SQL走hash join,可以的话并且加适当的并行,MySQL8.0不支持merge into

代码语言:javascript
复制
merge into orders o using 
(select o_orderkey
       from (
                SELECT ROW_NUMBER() OVER (PARTITION by O_ORDERPRIORITY ORDER BY O_TOTALPRICE DESC) as my_rowid,
                       o_orderkey
                from orders
                where O_ORDERDATE > '1998-01-01'
                  and O_ORDERDATE < '1998-12-30'
            ) x
       where x.my_rowid > 1) x
on (x.o_orderkey = o.o_orderkey)
when matched then update set o.O_TOTALPRICE = o.O_TOTALPRICE+1

那么我们看下执行计划,关于format=tree的使用可以参考https://cloud.tencent.com/developer/article/1876791这篇文章,但是很遗憾这个SQL不支持...

代码语言:javascript
复制
explain format=tree update tpch.orders set O_TOTALPRICE = O_TOTALPRICE + 1 where o_orderkey
          in
      (select o_orderkey
       from (
                SELECT ROW_NUMBER() OVER (PARTITION by O_ORDERPRIORITY ORDER BY O_TOTALPRICE DESC) as my_rowid,
                       o_orderkey
                from tpch.orders
                where O_ORDERDATE > '1998-01-01'
                  and O_ORDERDATE < '1998-12-30'
            ) x
       where x.my_rowid > 1
      );
--输出结果:
<not executable by iterator executor>

那么看普通版本的执行计划

被驱动表是没有索引的,这个SQL在MySQL中肯定是没办法执行出结果的,

表中一共几十万行数据,但是由于匹配因素,关联影响到了20亿行,那么到这里这个案例就结束了

结论:

MySQL并不适合OLAP数据分析型SQL,由于是在8.0支持分析函数的情况下,在生产中执行还是要小心,他并不向Oracle那么高效,还有需要提升学习的地方

那么,对于MySQL关联更新你有什么好的建议吗?

更多文章欢迎关注本人公众号,搜dbachongzi或扫二维码

作者:姚崇 Oracle OCM、MySQL OCP、Oceanbase OBCA、PingCAP PCTA认证,擅长基于Oracle、MySQL Performance Turning及多种关系型 NoSQL数据库

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • CPU100%
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档