当前位置: 首页 > 科技观察

限定两小时!一次由权限类型归集引发的紧急SQL优化案例

时间:2023-03-21 23:37:11 科技观察

限时两小时!一个由权限类型集合引发的紧急SQL优化案例SQL的内在成因,反思每个案例背后的深层思考。今天给大家分享第四个案例:获取负责人。需要回顾之前情况的同学请点击这里:Case1,Case2,Case3。1.Case这天,我项目组需要上线一个迭代版本。这是一个大版本,需要全员现场支持,上线后需要三天待命。1.一位不速之客,心地不善,就在上线前两天,也就是9月24日下午4点,本来风平浪静、有惊无险的性能优化突然陷入了混乱大招,某个页面被屏蔽了。检测到严重的性能问题,大致情况如下:测试人员在性能环境做了一轮压测,数据增长了5倍,其他功能点基本达到性能指标,而这个功能用了6s,完全超过了3s。一时间,所有人都紧张了起来。由于0926版本是一个大公司级别的版本,不仅我项目组会发布该版本,H公司的其他系统也会同时发布该版本。为了控制风险,代码会提前两天冻结。按照“生产无bug”的原则,我们必须在版本冻结结束时(9月24日18点)“杀死”这个性能bug列表。距离18:00不到2小时。PM闻讯后也高度关注,责令优化组全力攻关,求助。就这样,组长、模块SE和我组成了一个临时应急小组。大家全力以赴,很快就把问题整理出来了,大致如下:页面加载一共需要执行8条SQL,而且单条SQL执行时间不长,都在性能指标范围内,但总数超过5s;接下来的2s用于页面的逻辑处理。当时,组长当机立断。一方面,他要求把SQL优化到2s左右;另一方面,他将页面处理时间降低到1s以内,从而保证了3s的性能需求。SQL优化的任务自然落在了我的头上。8条SQL的代码如下:2.将士兵分成两组,将鸡蛋放在两个篮子里。***反应是:一页加载怎么会有8条SQL语句?这8条SQL语句之间有什么样的关系?它们可以合并为一个吗?如果做SQL合并,意味着我需要详细阅读这8条SQL,但是时间指针已经指向17:00,距离18:00下班还有不到一个小时。用一位中国足球解说员的话说,“现在留给中国队的时间不多了”,我也没有时间解读这8条SQL;此外,即使可以快速解释它们,它们也可能不会被合并。于是正如组长提出的:在单个SQL的优化上寻求突破口。8条SQL优化到2秒,也就是说单条SQL平均耗时0.25秒,压力也很大。和组长简单商量后,为了降低风险,避免把所有的鸡蛋都扔在一个篮子里,我做了如下决定:将部队分成两组,我来实施合并方案,优化的DBA团队负责优化单个SQL。3.是这样的,但是按照以往的习惯,我肯定会先自己解读这8条SQL,因为我相信别人的时间也是时间,自己能解决就尽量不要占用别人的时间.但是这次不行了,因为时间不允许,我得快速了解8条SQL的业务功能。于是我向SE表达了我的诉求,SE立刻安排开发负责人与我对接。经过与开发者20分钟的沟通,终于理清了8条SQL的逻辑和关系,如下:查询任务列表,共3条SQL,共耗时1s,主要SQL,包括count和详细查询Personincharge:4条SQL,共耗时3s,但是页面从上到下共耗时5s查询网络节点:1条SQL共耗时0.5s5s,这是重点关注的对象。继续询问开发负责人了解更多信息:“查询SQL负责人,单独运行SQL需要3秒,但是为什么页面需要5秒?”“因为页面需要判断SQL返回的数据集。”“都做了什么逻辑处理?”》这4条SQL对应四种权限,权限的最小单位是实体DU,对于任务列表中得到的DU,先用第一条SQL判断哪些DU有***类型的权限,比如DU有100个,所以第二条SQL传入的DU是90个DU,以此类推,我们就知道4类权限的判断都完成了。听完顿时豁然开朗,逻辑流程图如下:4、对症下药,一蹴而就,至此心里有了一个方案,四个SQL对应四个权限,如果我们把TASK_ID比作学生,USER_ID比作班级,权限比对学生选择的四个科目,那么“权限负责人查询”就转化为查询当前班级每个学生有***分的科目,这是一个按优先级排序后获得最大值的典型要求。目前的解决方案是:依次从DB中获取四种权限对应的DU_ID;JAVA中根据DB返回的权限判断权限类型。该方案存在两个性能瓶颈:将权限数据从DB传输到JAVA服务器会消耗一定的开销;性能问题。如果我们能够将权限类别的集合放在DB中,即DB只需要返回当前用户的DUID的权限类别,那么至少可以节省4倍的数据传输时间。当然,权限类型集合无论是放在DB还是JAVA,都是需要成本的,就看谁的算法更有优势了。事实上,Oracle提供了一个完整的解决方案,它使用rankover来实现优先级排序。这时,时间已经到了17点20分,我也无暇多想了。我立即合并并重写了查询负责人的4条SQL。合并SQL如下:改写后在DB中执行,耗时0.98秒。这意味着负责人查询已经成功从5s降到1s,整整下降了4s;这样就完全满足了整体的性能要求。我在17:25把SQL交给了开发,留给开发人员35分钟的时间去开发和验证。结果自然是皆大欢喜,项目顺利上线。二、体会1、学无止境的态度当SE拿到我合并的SQL时,满脸疑惑:“这个SQL是不是有问题?”“我是按照业务需求改写的,如果我没有理解错需求的话,SQL是正确的。”“是的,我测试了几个场景,结果似乎是正确的。”然后详细解释了Rank的作用和用法。SE长长的叹了口气说:“早知道Oracle有这么个‘神器’,所以一开始不用费心用Java做权限类型收集,而且还造成了性能问题。看来学无止境。”在这里,我无意苛求SE“我就知道是这样的,何必呢?毕竟艺术行业是有专攻的。唯一不明白的是,一个大的项目组(近200人)竟然没有DB开发工程师。建表、写SQL都是Java开发人员完成的。在与Java开发工程师的交流中了解到,有些人员根本没有SQL基础,更谈不上开发经验。他们写SQL的方式简单粗暴。他们从同事那里拿了一个类似功能的SQL,直接在其基础上修改,不知道SQL的具体含义。现在这种边学边卖的方式也直接导致很大的性能问题。正是因为DB开发工程师的岗位配置确定了SQL功能被大大削弱,以至于DB退化为单纯的数据存储功能,失去了真正的核心:组织和管理功能。作为世界500强企业,也是国内代表最高发展水平的企业,在企业管理系统的开发项目中,没有专职的DB开发工程师,其他公司开发团队的人员配置公司比较灵活。可以想象。2.一路走到底的理念性能优化组在组长的运筹帷幄下,为1017版本的性能做着准备,同时也很好的保证了926版本的性能需求,使得926版本顺利上线,我项目的PM也得意了一方面:在业绩红线上,终于没叫爷爷叫奶奶松口。926版本上线后,一方面表达感谢,另一方面为1017版本加油,PM设宴招待团队成员,并在会上问道:“黄工,来自你的观点是,这个项目在SQL方面有多大?”优化空间?”“这取决于性能需求和优化的决心。”SQL,所以应该给项目分配一个专职的DBA……”“呃,黄工,这不是“可以接受。如果是这样的话,那你在做什么?”领导就是领导,没有对抗,一切都轻描淡写的解释过了,后来看到内部资料中“现在固化,然后固化,再优化”的流程策略,才明白了一些。