首页 > 数据库 >不要使用count(列名)或count(常量)来替代count(*),count(*)就是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。

不要使用count(列名)或count(常量)来替代count(*),count(*)就是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。

时间:2023-09-18 16:44:10浏览次数:423  
标签:count 数据库 sql 无关 治理 SQL NULL

慢SQL治理经验总结 https://mp.weixin.qq.com/s/LZRSQJufGRpRw6u4h_Uyww

慢SQL治理经验总结

原创 药糖 大淘宝技术 2023-09-18 16:20 发表于浙江

 


在过去两年的工作中,我们团队曾负责大淘宝技术的慢SQL治理工作,作为横向的数据安全治理平台,如何快速准确地发现部门内所有应用的慢SQL,并进行高效的推动治理,同时覆盖多个开发、生产环境,是一个很大的挑战。以下是一些经验分享,我们通过持续的慢SQL推动治理,有效降低了DB相关的线上问题,极大提高了系统稳定性。

图片关于慢SQL
集团对于慢SQL的定义,执行超过1s的SQL为慢SQL。
慢SQL由于执行时间长,会导致:
  1. 系统的响应时间延迟,影响用户体验
  2. 资源占用增加,增高了系统的负载,其他请求响应时间也可能会收到影响。
  3. 慢SQL占用数据库连接的时间长,如果有大量慢SQL查询同时执行,可能会导致数据库连接池的连接被全部占用,导致数据连接池打满、缓冲区溢出等问题,使数据库无法响应其他请求。
  4. 还有可能造成锁竞争增加、数据不一致等问题

由此可见,需要及时发现和优化慢SQL,对保障系统稳定性是非常重要的。

 

图片慢SQL是如何引入的
产生慢SQL的原因可能有很多,以下是一些常见的原因:
  1. 缺乏索引/索引未生效,导致数据库全表扫描,会产生大量的IO消耗,产生慢SQL。
  2. 单表数据量太大,会导致加索引的效果不够明显。
  3. SQL语句书写不当,例如join或者子查询过多、in元素过多、limit深分页问题、order by导致文件排序、group by使用临时表等。
  4. 数据库在刷“脏页”,redo log写满了,导致所有系统更新被堵住,无法写入了。
  5. 执行SQL的时候,遇到表锁或者行锁,只能等待锁被释放,导致了慢SQL。

 

图片

如何发现慢SQL及高危SQL

 

  发现慢SQL

 

执行时常超过1s的为真实存在的慢SQL,阿里集团内部提供了很多可以方便获取应用慢SQL的方法,例如通过TDDL连接数据库,TDDL会将慢SQL日志统一记录到机器的tddl-slow.log文件中。集团内部的数据库服务中心也会提供相关的慢SQL数据查询记录以及接口。

对于外部用户,可以在数据库配置中启用慢查询日志功能,数据库会将执行时间超过一定阈值的慢SQL语句记录到日志中,也可以方便地获取慢查询日志。或者使用其他的数据库性能监控工具、SQL性能分析工具等。

 

  发现全量SQL

 

除了执行时长超过1s的慢SQL之外,我们还额外关注了未来可能劣化的慢SQL,这样就需要获取全量SQL,再对其进行分析,筛选出其中风险较大的SQL。我们采取了如下方法:

 

  • 基于JVM Sandbox进行SQL流水记录的采集

 

关于JVM Sandbox:「JVM-Sandbox提供动态增强你所指定的类,获取你想要的参数和行信息;提供动态可插拔容器,管理基于JVM-Sandbox的模块。」

 

简单来说,JVM Sandbox可以动态地将你要实现的代码模板打包编织到目标代码中,实现事件的监听、切入与代码增强。将目标代码的Java方法的调用分解为BEFORE、RETURN和THROWS三个环节,由此在三个环节上引申出对应环节的事件探测和流程控制机制。不仅如此,还有Line事件,可以完成代码行的记录。

 

// BEFORE-EVENTtry {    /*    * do something...    */
//LINE-EVENT
a();
// RETURN-EVENT return;
} catch (Throwable cause) { // THROWS-EVENT}

 

jvm-sandbox-repeater是JVM-sandbox生态体系下的重要模块,具备了JVM-Sandbox所有特点, 封装请求录制/回放基础协议,也提供了通用可拓展的丰富API。

 

repeator模块可以无侵入式地录制HTTP/Java/Dubbo入参/返回值,业务系统无感知。基于这个能力,我们可以方便的采集和SQL执行相关的Java方法参数以及返回值。通过配置采集点,来采集执行sql的java代码的相关方法、参数和返回值,辅助实现sql采集功能。

 

jvm-sandbox-repeater 地址:https://github.com/alibaba/jvm-sandbox-repeater?spm=ata.21736010.0.0.3e5975362i3rJi

  • 确认采集点

 

根据对MyBatis源码分析,我们确认了如下采集点:

图片

JVMSandbox完成数据采集后,通过发送metaq消息的方式,与系统进行对话。对于不同种类的采集消息,我们通过不同的字段加以匹配,最终可以获得每一条SQL流水对应的SQL文本、执行时长、sql参数、db名称、ip端口、sql_mapper资源文件等全部信息,具体如图所示:

图片

以上可以采集到应用的全部SQL,量级是很大的。我们采用了Blink创建时间窗口,进行数据聚合,实时数据处理,减少回流的在线数据量,在此就不展开说明了。

 

  如何识别高危SQL


根据历史慢SQL治理经验,我们把高危SQL分为以下几类:

  1. 不符合集团SQL规约的SQL,可能会埋坑,造成线上问题,影响执行效率等。

  2. 通过对SQL语句分析,发现SQL索引使用不当、造成全表扫描,或者SQL扫描行数过多、出现文件排序等。这种SQL即使当前不是慢SQL,随着表数据量的膨胀,未来也可能发展为慢SQL。

  3. SQL执行时间过长,比较容易理解。对慢SQL来说,执行时间越长,风险越高。


  • SQL规约


集团重点强制SQL规约如下:

  1. 【强制】不要使用count(列名)或count(常量)来替代count(*),count(*)就是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。

  2. 【强制】count(distinct col) 计算该列除NULL之外的不重复数量。注意 count(distinct col1, col2) 如果其中一列全为NULL,那么即使另一列有不同的值,也返回为0。

  3. 【强制】当某一列的值全是NULL时,count(col)的返回结果为0,但sum(col)的返回结果为NULL,因此使用sum()时需注意NPE问题。

  4. 【强制】使用ISNULL()来判断是否为NULL值。

  5. 【强制】对于数据库中表记录的查询和变更,只要涉及多个表,都需要在列名前加表的别名(或表名)进行限定。

  6. 【强制】在代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的分页语句。

  7. 【强制】不得使用外键与级联,一切外键概念必须在应用层解决。

  8. 【强制】禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。

  9. 【强制】IDB数据订正(特别是删除或修改记录操作)时,要先select,避免出现误删除,确认无误才能提交执行。

 

我们使用了Druid SQL Parser进行SQL解析,Druid SQL Parser是阿里巴巴的开源项目,可以将SQL语句解析为语法树,可以解析SQL的各个部分,如SELECT语句、FROM语、WHERE语句等,并且可以方便获取SQL语句的结构信息,如表名、列名、操作符等。通过分析SQL,可以轻松判断SQL是否符合规约。

 

  • SQL索引

 

SQL explain语句可以提供关于SQL查询执行的详细信息和执行计划,并且可以了解sql的索引使用情况以及数据访问方式。通过使用Explain语句,可以了解SQL是如何执行的,并且可以看出其可能存在的性能问题。
一个常见的返回结果示例如下:

图片

返回结果解析:

图片

我们重点关注的点如下:

  1. 使用全表扫描,性能最差,即type="ALL"

  2. 扫描行数过多,即rows>阈值

  3. 查询时使用了排序操作,也比较耗时,即Extra包含"Using filesort"

  4. 索引类型为index,代表全盘扫描了索引的数据,Extra信息为Using where,代表要搜索的列没有被索引覆盖,需要回表,性能较差。

 

以上几点都可能造成SQL性能的劣化,是我们需要额外关注的高风险sql。


图片如何推动治理慢SQL

 

作为横向的数据安全治理团队,为了对大淘宝技术部门进行慢SQL治理,我们建立了统一的问题发现-追踪-治理机制。慢SQL治理中涵盖了生产环境、开发环境的慢SQL,区别在于:生产环境中为已经上线的存量慢SQL,开发环境中为新引入的慢SQL,对开发环境引入的慢SQL,修复代价要小于生产环境。接下来分别介绍。

 

  存量慢SQL治理


存量慢SQL治理的难点在于,历史遗留下的慢SQL可能量级很大,所以要区分慢SQL治理的优先级。我们制定了健康分机制,对SQL分批分级治理。

 

对慢SQL来说,健康分主要受SQL的执行次数、扫描行数、执行时长影响。另外根据应用中包含慢SQL的数量、平均SQL执行数据等,给应用打出健康分。再根据部门维度汇总,根据应用等级、应用健康分情况等,计算出部门维度的健康分。
整体流程大致如下:

图片


在慢SQL推动治理方面,高危慢SQL,会建立Issue持续追踪,Issue存在超期时间,超期后会影响团队健康分。另外,提供应用维度、部门维度的整体慢SQL风险大盘以及排名,针对重点业务、慢SQL高发团队等,进行集中的推进治理。

 

  增量慢SQL治理

 

我们希望增量慢SQL能在上线前得到解决,即分支内不要引入慢SQL或者风险SQL,所以结合3.2和3.3,我们建立了开发环境下增量慢SQL发现机制,并建立发布前卡点能力。整体流程如下:

图片

 

增量慢SQL的修复代价是小于存量慢SQL的,因此这里我们添加了分支定位的能力。同一应用存在多个同学共同开发的情况,有效的分支定位,可以准确指派慢SQL引入人,实现快速推动治理。这里以git上代码改动为切入点,完成了引入慢SQL的sql_map与修改人之间的关系映射,大致逻辑如下:

 

a. 监听应用部署消息

b. 获取应用信息,拿到git地址

c. 将本次部署分支与master分支做分支diff

d. 解析sql_map文件,获取本次修改的sql内容

e. 记录被修改sql_id与分支的对应关系

f. 根据sql_id查询对应分支

……

 

这样就可以精准匹配到增量SQL的引入分支,从而指派到开发者,实现了定向问题指派和追踪,并且可以方便完成分支发布前的管控能力。如果存在增量慢SQL,分支发布,合并到master之前,会触发卡点,需要问题解决才能发布。

 

  安全生产环境慢SQL治理

 

安全生产环境(SPE环境),是集团层面为保障线上稳定性的灰度流量生产环境,安全生产环境执行过的慢SQL,在线上流量放大后,可能会对DB造成过大的压力。我们额外新增了安全生产环境慢SQL的管控,作为开发环境下SQL被引入到线上的最后一道防线。

 

整体方案与上面慢SQL治理方案类似,在此就不赘述了。

 

图片总结

慢SQL可能引起很严重的系统性能问题,影响系统可用性和稳定性,因此,及时发现和治理慢SQL是十分重要的。我们建了一套完整的慢SQL发现-分析-推动治理的机制,极大减少了由慢SQL引发的系统问题。同时,在db稳定性上,我们还额外关注数据库CPU使用情况、活跃会话数情况等,建立及时的风险预警和快恢机制,第一时间解决数据库风险。

 

图片

团队介绍

 

营销与平台策略技术团队是淘天集团的核心部门之一,负责淘天集团核心用户产品——搜索、拍立淘,并支撑双11、618、年货节等大型活动,百亿补贴、淘宝好价、聚划算等营销产品。通过优惠券、跨店满减、直降、会员卡等多种营销工具的创新和沉淀,基于商品的搜索引擎建设对搜索产品的探索,招商、选品、搭建、投放的活动支撑链路的建设,以平台化、数据化、智能算法等方式支撑了以大淘宝为主的集团核心平台营销场景,全力为淘宝天猫打造有乐趣的购物体验。在这里可以接触到最前沿的人工智能产品和大数据开发体系,在数据和创新驱动下,为数亿用户提供优质服务。
若你对我们的工作内容感兴趣,欢迎加入挑战,简历(研发、前端、测开)投递邮箱:[email protected]

 

 

 

 

翻译

搜索

复制

标签:count,数据库,sql,无关,治理,SQL,NULL
From: https://www.cnblogs.com/papering/p/17712359.html

相关文章

  • 关于 Spartacus My Account 菜单的数据源 - NavigationNode
    有朋友询问Spartacus的MyAccount菜单里,Mycompany菜单项的数据源是什么?Spartacus启动时,我们观察到这个OCCAPI:/occ/v2/powertools-spa/cms/pages?lang=en&curr=USD在其响应数据里,观察到navigationnode里包含了一个叫做MyCompany的菜单项:Backoffice是SAPCom......
  • springboot+html使用sql语句能够在控制台输出相关数据信息list,但是输出的list=null(未
    问题描述具体来说,就是,连接上数据库之后,发现查询的sql语句能够正常在控制台输出数据,但是将sql语句的查询结果放到list里面,在控制台输出的list=[null];真的崩溃了!!!之前从来没有遇到过这种情况;尝试了网上的各种方法,也都解决不了,麻木ing~求解!......
  • odoo to account move
    allmodel:stock_valuation_layers._check_company()self._check_company()stock.valuation.layer=>account.movestock_valuation_layers._validate_accounting_entries()account.move=>postaccount_moves=self.env['account.move'].sudo().create(......
  • scrap -> accountmove 参考
    defaction_validate(self):self.ensure_one()iffloat_is_zero(self.scrap_qty,precision_rounding=self.product_uom_id.rounding):raiseUserError(_('Youcanonlyenterpositivequantities.')......
  • account.move create
     https://www.odoo.com/zh_CN/forum/bang-zhu-1/how-to-insert-value-to-a-one2many-field-in-table-with-create-method-28714?forum=forum.forum%281%2C%29&question=forum.post%2828714%2C%29 https://www.odoo.com/zh_CN/forum/bang-zhu-1/create-automatic-journa......
  • SQL查询中的小技巧:SELECT 1 和 LIMIT 1 替代 count(*)
    前言在写SQL查询时,常规做法是使用SELECTcount(*)来统计符合条件的记录数。然而,在某些情况下,我们只关心是否存在符合条件的记录,而不需要知道具体的记录数。为了优化性能,可以改用使用SELECT1和LIMIT1的方式查询。在业务代码中,直接判断查询结果是否非空即可,不再需要使......
  • java的jdbc插入的时候,遇到null情况报错问题
    分析原因:在执行SQL时MyBatis会自动通过对象中的属性给SQL中参数赋值,它会自动将Java类型转换成数据库的类型。而一旦传入的是null它就无法准确判断这个类型应该是什么,就有可能将类型转换错误,从而报错。解决办法:参数增加jdbcType标识数据类型。(注意:这时候参数{}前统一用#)<inser......
  • C# 性能诊断工具 dotnet-counters 的使用
    创建.NET程序Dump的几种姿势下载dotnet-counters工具简介dotnet-counters是一个性能监视工具,用于初级运行状况监视和性能调查。它通过EventCounterAPI观察已发布的性能计数器值。例如,可以快速监视CUP使用情况或.NETCore应用程序中的异常率等指标安装通过nuget包安装:......
  • 日常踩坑_关于cassandra使用了count(1)又又又超时了
    背景提要由于习惯了用Mysql和Oracle这种数据库,切换到Cassandra之后真是踩了一系列的坑本来是一个简单的请求,Ijustwant简简单单求个表的总行数而表也不是什么千万级别的大表,just只是小小的几千条数据而已,然而cassandra非常给面子,本应该在千万级别查询才出的错,出现在了我一张......
  • js中使用0 “” null undefined {}需要注意 if判断时候都是false,比如判断接收后台数
    js中使用0“”nullundefined{}需要注意if判断时候都是false,比如判断接收后台数据if(data.info){}注意:在js中0为空(false),代表空的还有“”,null,undefined;如果做判断if(!上面的四种值);返回均为false?1234567console.log(!null);//trueconsole.log(!0);//trueconsole.lo......