前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >20年IT老兵的参赛感悟:永远不要停止前进的步伐!

20年IT老兵的参赛感悟:永远不要停止前进的步伐!

作者头像
腾讯云数据库 TencentDB
发布2019-12-03 17:10:48
8310
发布2019-12-03 17:10:48
举报
文章被收录于专栏:腾讯云数据库(TencentDB)

?

我叫赵文新,现任职于朗朗医疗投资有限公司DBA,是一个二十年的IT老男孩,非常荣幸能够参加由腾讯云组织的DB王者数据库诊断赛,并在本次比赛中获得二等奖。感谢腾讯云提供的高质量、理论实践相结合的MySQL学习机会,让我们的技能得到快速提升。在此我想和这次结识的小伙伴们一起,感谢腾讯,希望腾讯云数据库发展的越来越好,希望每个人永远不要停止前进的步伐!

前段时间比较忙,今天我把比赛思路整理了一下,希望和大家一起继续交流,共同提高。水平有限,欢迎大家多多斧正!第4条语句大家可有更好的思路?可以后台留言或者添加我的QQ3375887316交流。

比赛初赛赛题解析请至文末查看,决赛官方解析请点击☞首届腾讯云数据库王者挑战赛落幕,决赛选手无一超越AI

一、原表结构:

代码语言:javascript
复制
create table region  (
       regionkey  integer not null,
       name       varchar(25) not null,
       comment    varchar(152),
       primary key(regionkey)
);
create table nation  (
       nationkey  integer not null,
       name       varchar(25) not null,
       regionkey  integer not null,
       comment    varchar(152),
       primary key(nationkey)
);
create table customer (
        custkey     integer not null,
        name        varchar(25) CHARACTER SET utf8 COLLATE utf8_bin not null,
        address     varchar(40) not null,
        nationkey   integer not null,
        phone       varchar(15) not null,
        acctbal     decimal(15,2)   not null,
        mktsegment  varchar(10) not null,
        comment     varchar(117) not null,
        primary key(custkey)
    );
create table orders  (
        orderkey       integer not null,
        custkey        integer not null,
        orderstatus    varchar(1) not null,
        totalprice     decimal(15,2) not null,
        orderdate      date not null,
        orderpriority  varchar(15) not null,
        clerk          varchar(15) not null,
        shippriority   integer not null,
        comment        varchar(79) not null,
        primary key(orderkey)
    );

二、待优化SQL语句1:

代码语言:javascript
复制
select c.custkey, c.phone,sum(o.totalprice) totalprice
   from nation n
   inner join customer c on c.nationkey = n.nationkey
   inner join orders o on o.clerk = c.name
   where n.name = "CHINA" and c.mktsegment ="HOUSEHOLD" and c.phone like "28-520%"
group by c.custkey, c.phone;

三、优化思路:

这是3表连接查询,所有第一考虑的方向是驱动表选择。group by在5.7版本时会有一个隐藏排序,考虑用c表做驱动表,用group by的字段来做索引,避免结果排序。

在where中c表有mktsegment,phone;如果能全部包含在复合索引中,有可能实现using index不用回表。在from中c表有nationkey,name;如果能全部包含在复合索引中,有可能实现using index不用回表。复合索引(custkey,phone,mktsegment,nationkey,name)字段过多,len长度过长。

综合考虑c表的写入性能,仅使用primary key(custkey,phone),好处有:

避免结果排序;利用索引中的phone字段,从引擎层排除一部分rows,在服务层再去除mktsegment不符的rows。被驱动表n的nationkey需要索引,本来就是主键不需要新建;o表的clerk需要索引,增加索引。

语句不用修改;索引alter语句:

代码语言:javascript
复制
ALTER TABLE customer DROP  PRIMARY key, ADD PRIMARY key (custkey,phone);
ALTER TABLE orders ADD index (clerk);

四、待优化SQL语句2:

代码语言:javascript
复制
select *
   from (
       select custkey, orderdate, sum(totalprice) as totalprice
       from orders
       group by custkey, orderdate
    ) t
where orderdate= "2019-08-01";

五、优化思路:

只有一个表,子查询后再where筛选;应该将选择和投影一次完成;

和第一条语句一样有个隐含排序的group by,考虑用(custkey,orderdate)复合索引;

如果将select中的totalprice字段,也加到索引中,可以实现using index不用回表;

但是为了考虑写入性能,不使用len太长,字段过多的复合索引;最终使用复合索引(custkey,orderdate)

六、优化后语句:

代码语言:javascript
复制
select custkey, orderdate, sum(totalprice) as totalprice
    from orders
    where orderdate= "2019-08-01"
    group by custkey, orderdate;

索引alter语句:

代码语言:javascript
复制
ALTER TABLE orders ADD key (custkey,orderdate);

七、待优化SQL语句3:

代码语言:javascript
复制
select c.custkey, sum(o.totalprice)totalprice
   from customer c
   left join orders o on o.custkey = c.custkey
   where c.phone like "33-64%" and c.name like concat("Customer#00003", "%")
group by c.custkey;

八、优化思路:

两表连接,选择驱动表;隐含排序的group by;where中的c表字段phone,name;

选择c表驱动,考虑复合索引(custkey,phone,name),综合考虑写性能使用(custkey,phone),在优化第一条语句时已经建立;

被驱动表o的custkey字段需要索引,在优化第二条语句时,已经是复合索引的最左字段,不用新建。

九、待优化SQL语句4:

代码语言:javascript
复制
select c.custkey, c.phone
   from nation n
   inner join customer c on c.nationkey = n.nationkey
   where n.name = "CHINA" and exists (
       select 1 from orders o where o.custkey = c.custkey and o.orderdate ="1998-08-11"
    );

十、优化思路:

exists的子查询,可以用join distinct来实现,效率更高;

代码语言:javascript
复制
select c.custkey, c.phone
   from nation n
   inner join customer c
   on c.nationkey = n.nationkey
   inner join (select distinct custkey from orders where orderdate ="1998-08-11") o
   on o.custkey = c.custkey
   where n.name = "CHINA";

变子查询为<derived>表连接;3表连接,选择驱动表;

这时有两个选择:

选择1:where 字段有<derived>表的orderdate,可以使用auto_key(custkey,orderdate)索引,<derived>来做驱动表;

被驱动表c表custkey需要索引,优化第一条语句时,已是复合索引的最左字段;n表nationkey需要索引,本是主键,不用新建;不需要新建索引;在测试时出现c,n表不使用主键,为什么?强制join顺序,需要强制使用索引;修改语句如下:

代码语言:javascript
复制
select c.custkey, c.phone
   from
   (select distinct custkey from orders where orderdate ="1998-08-11") o
   straight_join
   customer c force index(primary) on  o.custkey = c.custkey
   straight_join
   nation n force index(primary) on c.nationkey = n.nationkey and n.name = "CHINA";

选择2: where字段有n表的name,可以使用index(name)索引,需要新建,n表来做驱动表;

被驱动表c表nationkey需要新建索引;<derived>表custkey需要索引,已有auto_key(custkey,orderdate),不用新建;

语句使用第一步优化后的即可;索引alter语句如下:

代码语言:javascript
复制
alter table customer add index(nationkey);alter table nation add index(name);

n表index(name)长度102,还多了一个c表的index(nationkey),现在只有表结构,没有数据,具体是哪个方法更好,待大家评议。

我本人倾向于选择1,如果执行时间不是太慢,我觉得还是不要建太多索引。但是为什么需要force index()才能执行想要的执行计划?是没有数据吗?

选择2因为减少了n表的rows肯定是select更快,但是多了两个索引,影响n表和c表写入效率的。

DB诊断日教学实例有奖征集

为更好的帮助DBA运维数据库,腾讯云将在每月6日开展DB诊断日,腾讯云高级产品经理迪B哥直播解析经典数据库运维难题,结合腾讯云数据库智能管家DBbrain的能力,为大家提供问题优化思路和方法,玩转数据库!

工作中遇到棘手故障不知道怎么办?欢迎投稿到诊断日,被选中的案例将由腾讯云资深专家“会诊”,并在DB诊断日在线分析教学,帮您提供解决方案。投稿即有机会获得企鹅公仔,问题被选中即得腾讯云数据库千元代金券~扫描下方二维码添加好友,并备注“投稿”即可参与!

往期推荐

(点击图片即可跳转阅读)

疯狂11.11

11月1日-12月2日, MySQL低至2.5折起,SQL Server 2折起,Redis2.5折起,参与每天5场秒杀,超低价格购买数据库产品。企业新用户及个人新用户可领取千元代金券,企业版最高3200元代金券(满8000可用);个人最高1500元代金券(满3750可用)。

↓↓点击阅读原文拼手速啦~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云数据库 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

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