苏三说技术

其他

MySQL索引优化20招

Java突击网站:http://www.susan.net.cn,强烈建议收藏。前言索引的相信大家都听说过,但是真正会用的又有几人?平时工作中写SQL真的会考虑到这条SQL如何能够用上索引,如何能够提升执行效率?此篇文章详细的讲述了索引优化的几个原则,只要在工作中能够随时应用到,相信你写出的SQL一定是效率最高,最牛逼的。文章的脑图如下:索引优化规则1、like语句的前导模糊查询不能使用索引select
2023年7月8日
其他

分布式夺命12连问

P理论上放弃P(分区容错性),则C(强一致性)和A(可用性)是可以保证的。实际上分区是不可避免的,严格上CA指的是允许分区后各子系统依然保持CA。CA模型的常见应用:集群数据库xFS文件系统CP
2023年2月21日
其他

高质量学习社群

苏三的知识星球【Java突击队】,已经运营了一段时间了。目前已经更新了很多独家的干货内容,比如:Java后端学习路线,源码分析,百万级系统设计,系统上线的一些坑,MQ专题,真实面试题,每天都会回答大家提出的问题,和一些非常有价值的学习资料。【Java突击队】知识星球计划如下:分享工作中的踩坑经历,让你快速获取工作经验,少走很多弯路。分享工作中非常实用的开发技巧,助你写出优雅的代码。分享工作中好用的开发小工具,助你提升开发效率。分享工作中常用的框架,比如:Spring、Mybatis等源码解读。分享面试资料。分享技术类书籍。回答每天球友的问题。打算一个活跃干货满满的技术社群。感谢大家对苏三分享的以往文章的认可,和对苏三的技术能力的信任。目前有390+的小伙伴,加入了苏三的知识星球,和我一起学习,相互帮助,一起进步,共同成长。目前得到了大家的一致好评。在知识星球中,我基本上每天都会分享一些干货内容:也会分享很多面试资料:这里其实是一个高质量的学习社区,在这里你可以轻松获取很多公众号上没有的干货内容和资料,也可以跟更多优秀的人一起学习,一起交流技术。由于刚开始运营,门槛设置得非常低,后面肯定要涨价的,今天特地给大家申请了一波优惠券,现在入手非常划算。原价109元,使用优惠券84元就能上车(后面干货越来越多,肯定要涨价的)。星球中你可以开阔一下视野,跟一群优秀的人一起交流和学习,如果工作中有些难题也有人给你出谋划策,这个价格超值!说实话84元这个价格已经非常便宜了,可能就是一顿饭钱,qq音乐听个歌都要100多一年。但我相信知识星球回馈给你的,将来是十倍或者百倍的价值。
2023年2月15日
其他

糟了,线上服务出现OOM了

大家好,我是苏三,又跟大家见面了。前言前一段时间,公司同事的一个线上服务OOM的问题,我觉得挺有意思的,在这里跟大家一起分享一下。我当时其实也参与了一部分问题的定位。1
2022年10月10日
其他

明明加了唯一索引,为什么还是产生重复数据?

大家好,我是苏三,又跟大家见面了。文末留言送书啦!!!前言前段时间我踩过一个坑:在mysql8的一张innodb引擎的表中,加了唯一索引,但最后发现数据竟然还是重复了。到底怎么回事呢?本文通过一次踩坑经历,聊聊唯一索引,一些有意思的知识点。1.还原问题现场前段时间,为了防止商品组产生重复的数据,我专门加了一张防重表。如果大家对防重表,比较感兴趣,可以看看我的另一篇文章
2022年8月4日
其他

高并发下如何防重?

大家好,我是苏三,又跟大家见面了。文末留言送书啦!!!前言最近测试给我提了一个bug,说我之前提供的一个批量复制商品的接口,产生了重复的商品数据。追查原因之后发现,这个事情没想象中简单,可以说一波多折。1.
2022年6月11日
其他

吐血推荐17个提升开发效率的“轮子”

大家好,我是苏三,又跟大家见面了。前言在java的庞大体系中,其实有很多不错的小工具,也就是我们平常说的:轮子。如果在我们的日常工作当中,能够将这些轮子用户,再配合一下idea的快捷键,可以极大得提升我们的开发效率。今天我决定把一些压箱底的小工具,分享给大家,希望对你有所帮助。本文会分享17个我们日常工作中一定会用得到的小工具,主要内容如下:1.
2022年5月27日
其他

ThreadLocal夺命11连问

大家好,我是苏三,又跟大家见面了。文末留言送书啦!!!前言前一段时间,有同事使用ThreadLocal踩坑了,正好引起了我的兴趣。所以近期,我抽空把ThreadLocal的源码再研究了一下,越看越有意思,发现里面的东西还真不少。我把精华浓缩了一下,汇集成了下面11个问题,看看你能顶住第几个?1.
2022年5月14日
其他

被自己坑了...

大家好,我是苏三,又跟大家见面了。文末送书啦!!!前言前段时间,我们线上系统出现了一个事故:用户创建了商品,在商城的商品列表页看不到,也搜索不到。、这个问题持续了大概半个小时,最后发现竟然是我的锅。这个事情怎么说呢,完全是我自己把自己坑了。到底怎么回事呢?1.
2022年4月8日
其他

如何保证数据库和缓存双写一致性?

大家好,我是苏三,又跟大家见面了。前言数据库和缓存(比如:redis)双写数据一致性问题,是一个跟开发语言无关的公共问题。尤其在高并发的场景下,这个问题变得更加严重。我很负责的告诉大家,该问题无论在面试,还是工作中遇到的概率非常大,所以非常有必要跟大家一起探讨一下。今天这篇文章我会从浅入深,跟大家一起聊聊,数据库和缓存双写数据一致性问题常见的解决方案,这些方案中可能存在的坑,以及最优方案是什么。1.
2022年3月31日
其他

Objects.equals有坑

大家好,我是苏三,又跟大家见面了。文末送书啦!!!前言最近review别人代码的时候,发现有个同事,在某个业务场景下,使用Objects.equals方法判断两个值相等时,返回了跟预期不一致的结果,引起了我的兴趣。原本以为判断结果会返回true的,但实际上返回了false。记得很早之前,我使用Objects.equals方法也踩过类似的坑,所以有必要把这个问题记录下来,分享给大家。到底怎么回事呢?1.
2022年3月21日
其他

如何写出让人抓狂的代码?

大家好,我是苏三,又跟大家见面了。前言今天跟大家聊一个有趣的话题:如何写出让人抓狂的代码?大家看到这个标题,第一印象觉得这篇文章可能是一篇水文。但我很负责的告诉你,它是一篇有很多干货的技术文。曾几何时,你在阅读别人代码的时候,有没有抓狂,想生气,想发火的时候?今天就跟大家一起聊聊,这20种我看了会抓狂的代码,看看你中招了没?1.不注重代码格式代码格式说起来很虚,下面我用几个案例演示一下,不注重代码格式的效果。作为这篇文章的开胃小菜吧。1.1
2022年2月8日
其他

聊聊索引失效的10种场景,太坑了

大家好,我是苏三,又跟大家见面了。前言我之前写的一篇文章《聊聊sql优化的15个小技巧》,自发表之后,在全网广受好评,被很多大佬转载过,说明了这类文章的价值。今天我接着上一期数据库的话题,更进一步聊聊索引的相关问题,因为索引是大家都比较关心的公共话题,确实有很多坑。不知道你在实际工作中,有没有遇到过下面的这两种情况:明明在某个字段上加了索引,但实际上并没有生效。索引有时候生效了,有时候没有生效。今天就跟大家一起聊聊,mysql数据库索引失效的10种场景,给曾经踩过坑,或者即将要踩坑的朋友们一个参考。1.
2022年1月9日
自由知乎 自由微博
其他

烂大街的缓存穿透、缓存击穿和缓存雪崩,你真的懂了?

大家好,我是苏三,又跟大家见面了。祝大家圣诞节快乐,文末送书!!!前言对于从事后端开发的同学来说,缓存已经变成的项目中必不可少的技术之一。没错,缓存能给我们系统显著的提升性能。但如果你使用不好,或者缺乏相关经验,它也会带来很多意想不到的问题。今天我们一起聊聊如果在项目中引入了缓存,可能会给我们带来的下面这三大问题。看看你中招了没?1.
2021年12月25日
其他

聊聊接口性能优化的11个小技巧

大家好,我是苏三,又跟大家见面了。前言接口性能优化对于从事后端开发的同学来说,肯定再熟悉不过了,因为它是一个跟开发语言无关的公共问题。该问题说简单也简单,说复杂也复杂。有时候,只需加个索引就能解决问题。有时候,需要做代码重构。有时候,需要增加缓存。有时候,需要引入一些中间件,比如mq。有时候,需要需要分库分表。有时候,需要拆分服务。等等。。。导致接口性能问题的原因千奇百怪,不同的项目不同的接口,原因可能也不一样。本文我总结了一些行之有效的,优化接口性能的办法,给有需要的朋友一个参考。1.索引接口性能优化大家第一个想到的可能是:优化索引。没错,优化索引的成本是最小的。你通过查看线上日志或者监控报告,查到某个接口用到的某条sql语句耗时比较长。这时你可能会有下面这些疑问:该sql语句加索引了没?加的索引生效了没?mysql选错索引了没?1.1
2021年11月18日
其他

聊聊sql优化的15个小技巧

大家好,我是苏三,又跟大家见面了。前言sql优化是一个大家都比较关注的热门话题,无论你在面试,还是工作中,都很有可能会遇到。如果某天你负责的某个线上接口,出现了性能问题,需要做优化。那么你首先想到的很有可能是优化sql语句,因为它的改造成本相对于代码来说也要小得多。那么,如何优化sql语句呢?这篇文章从15个方面,分享了sql优化的一些小技巧,希望对你有所帮助。1
2021年11月10日
其他

阿里二面:为什么要分库分表?

大家好,我是苏三,又跟大家见面了。前言在高并发系统当中,分库分表是必不可少的技术手段之一,同时也是BAT等大厂面试时,经常考的热门考题。你知道我们为什么要做分库分表吗?这个问题要从两条线说起:垂直方向
2021年10月27日
其他

单例模式,真不简单

大家好,我是苏三,又跟大家见面了。前言单例模式无论在我们面试,还是日常工作中,都会面对的问题。但很多单例模式的细节,值得我们深入探索一下。这篇文章透过单例模式,串联了多方面基础知识,非常值得一读。1
2021年10月19日
其他

@Value竟然能玩出这么多花样

大家好,我是苏三,又跟大家见面了。前言对于从事java开发工作的小伙伴来说,spring框架肯定再熟悉不过了。spring给开发者提供了非常丰富的api,满足我们日常的工作需求。如果想要创建bean实例,可以使用@Controller、@Service、@Repository、@Component等注解。如果想要依赖注入某个对象,可以使用@Autowired和@Resource注解。如果想要开启事务,可以使用@Transactional注解。如果想要动态读取配置文件中的某个系统属性,可以使用@Value注解。等等,还有很多。。。前面几种常用的注解,在我以往的文章《@Autowired的这些骚操作,你都知道吗?》《聊聊spring事务失效的12种场景,太坑了》《惊呆了,spring中竟然有12种定义bean的方法》中已经介绍过了,在这里就不过多讲解了。今天咱们重点聊聊@Value注解,因为它是一个非常有用,但极其容易被忽视的注解,绝大多数人可能只用过它的一部分功能,这是一件非常遗憾的事情。所以今天有必要和大家一起,重新认识一下@Value。1.
2021年10月11日
其他

聊聊redis分布式锁的8大坑

大家好,我是苏三,又跟大家见面了。前言在分布式系统中,由于redis分布式锁相对于更简单和高效,成为了分布式锁的首先,被我们用到了很多实际业务场景当中。但不是说用了redis分布式锁,就可以高枕无忧了,如果没有用好或者用对,也会引来一些意想不到的问题。今天我们就一起聊聊redis分布式锁的一些坑,给有需要的朋友一个参考。1
2021年9月24日
其他

聊聊spring事务失效的12种场景,太坑了

大家好,我是苏三,又跟大家见面了。前言对于从事java开发工作的同学来说,spring的事务肯定再熟悉不过了。在某些业务场景下,如果一个请求中,需要同时写入多张表的数据。为了保证操作的原子性(要么同时成功,要么同时失败),避免数据不一致的情况,我们一般都会用到spring事务。确实,spring事务用起来贼爽,就用一个简单的注解:@Transactional,就能轻松搞定事务。我猜大部分小伙伴也是这样用的,而且一直用一直爽。但如果你使用不当,它也会坑你于无形。今天我们就一起聊聊,事务失效的一些场景,说不定你已经中招了。不信,让我们一起看看。一
2021年9月4日
其他

innodb是如何存数据的?yyds

hi,大家好,我是苏三,又跟大家见面了。前言如果你使用过mysql数据库,对它的存储引擎:innodb,一定不会感到陌生。众所周知,在mysql5以前,默认的存储引擎是:myslam。但mysql5之后,默认的存储引擎已经变成了:innodb,它是我们建表的首选存储引擎。那么,问题来了:innodb底层是如何存储数据的?表中有哪些隐藏列?用户记录之间是如何关联起来的?如果你想知道上面三个问题的答案,那么,请继续往下面看。本文主要包含如下内容:1.磁盘or内存?1.1
2021年8月23日
其他

10个解放双手实用在线工具,有些代码真的不用手写

的所有功能,又在其基础上增加了很多实用功能,它几乎可以集成当下所有主流技术,只要勾选相应的模块就可以自动集成进来。可不是简单的引入jar包,而是帮你把工程目录,相关配置文件和基础
2021年8月9日
其他

@Autowired的这些骚操作,你都知道吗?

hi,大家好,我是苏三,又跟大家见面了。前言最近review别人代码的时候,看到了一些@Autowired不一样的用法,觉得有些意思,特定花时间研究了一下,收获了不少东西,现在分享给大家。也许@Autowired比你想象中更强大。1.
2021年8月5日
其他

惊呆了,spring中竟然有12种定义bean的方法

前言在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜。我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工作中的多种业务场景。那么问题来了,你知道spring中有哪些方式可以定义bean?我估计很多人会说出以下三种:没错,但我想说的是以上三种方式只是开胃小菜,实际上spring的功能远比你想象中更强大。各位看官如果不信,请继续往下看。1.
2021年7月5日
其他

生产环境一次诡异的NPE问题,反转了4次

大家好,我是苏三,又跟大家见面了。前言公司为了保证系统的稳定性,加了很多监控,比如:接口响应时间、cpu使用率、内存使用率、错误日志等等。如果系统出现异常情况,会邮件通知相关人员,以便于大家能在第一时间解决隐藏的系统问题。此外,我们这边有个不成文的规定,就是线上问题最好能够当日解决,除非遇到那种非常棘手的问题。1.起因有个周一的早上,我去公司上班,查看邮件,收到我们老大转发的一封邮件,让我追查线上的一个NPE(NullPointException)问题。邮件是通过sentry发出来的,我们通过点击邮件中的相关链接,可以直接跳转到sentry的详情页面。在这个页面中,展示了很多关键信息,比如:操作时间、请求的接口、出错的代码位置、报错信息、请求经过了哪些链路等等。真是居家旅行,查bug的良药,有了这些,小case一眼就能查到原因。我当时没费吹灰之力,就访问到了NPE的sentry报错页面(其实只用鼠标双击一下就搞定)。果然上面有很多关键信息,我一眼就看到了NPE的具体代码位置:notify.setName(CurrentUser.getCurrent().getUserName());剧情发展得如此顺利,我都有点不好意思了。根据类名和代码行号,我在idea中很快找到那行代码,不像是我写的,这下可以放心不用背锅了。于是接下来看了看那行的代码修改记录,最后修改人是XXX。什么?是他?他在一个月前已经离职了,看来这个无头公案已经无从问起,只能自己查原因。我当时内心的OS是:代码没做兼容处理。为什么这么说呢?这行代码其实很简单,就是从当前用户上下文中获取用户名称,然后设置到notify实体的inUserName字段上,最终notify的数据会保存到数据库。该字段表示那条推送通知的添加人,正常情况下没啥卵用,主要是为了出现线上问题扯皮时,有个地方可以溯源。如果出现冤案,可以还你清白。顺便提一嘴,这里说的推送通知跟mq中的消息是两回事,前者指的是websocket长连接推送的实时通知,我们这边很多业务场景,在页面功能操作完之后,会实时推送通知给指定用户,以便用户能够及时处理相关单据,比如:您有一个审批单需要审批,请及时处理等。CurrentUser内部包含了一个ThreadLocal对象,它负责保存当前线程的用户上下文信息。当然为了保证在线程池中,也能从用户上下文中获取到正确的用户信息,这里用了阿里的TransmittableThreadLocal。伪代码如下:@Datapublic
2021年6月19日
其他

mq的那些破事儿,你不好奇吗?

引入mq会多哪些问题?引入mq后让我们子系统间耦合性降低了,异步处理机制减少了系统的响应时间,同时能够有效的应对请求峰值问题,提升系统的稳定性。但是,引入mq同时也会带来一些问题。3.1
2021年5月6日
其他

学会这10种定时任务,我有点飘了

大家好我是苏三,又跟大家见面了。前言最近有几个读者私信给我,问我他们的业务场景,要用什么样的定时任务。确实,在不用的业务场景下要用不同的定时任务,其实我们的选择还是挺多的。我今天给大家总结10种非常实用的定时任务,总有一种是适合你的。一.
2021年4月10日
其他

高并发下如何保证接口的幂等性?

前言接口幂等性问题,对于开发人员来说,是一个跟语言无关的公共问题。本文分享了一些解决这类问题非常实用的办法,绝大部分内容我在项目中实践过的,给有需要的小伙伴一个参考。不知道你有没有遇到过这些场景:有时我们在填写某些form表单时,保存按钮不小心快速点了两次,表中竟然产生了两条重复的数据,只是id不一样。我们在项目中为了解决接口超时问题,通常会引入了重试机制。第一次请求接口超时了,请求方没能及时获取返回结果(此时有可能已经成功了),为了避免返回错误的结果(这种情况不可能直接返回失败吧?),于是会对该请求重试几次,这样也会产生重复的数据。mq消费者在读取消息时,有时候会读取到重复消息(至于什么原因这里先不说,有兴趣的小伙伴,可以找我私聊),如果处理不好,也会产生重复的数据。没错,这些都是幂等性问题。接口幂等性是指用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。这类问题多发于接口的:insert操作,这种情况下多次请求,可能会产生重复数据。update操作,如果只是单纯的更新数据,比如:update
2021年3月28日
其他

盘点一下数据库的误操作有哪些后悔药?

前言无论是开发、测试,还是DBA,都难免会涉及到数据库的操作,比如:创建某张表,添加某个字段、添加数据、更新数据、删除数据、查询数据等等。正常情况下还好,但如果操作数据库时出现失误,比如:删除订单数据时where条件写错了,导致多删了很多用户订单。更新会员有效时间时,一次性把所有会员的有效时间都更新了。修复线上数据时,改错了,想还原。还有很多很多场景,我就不一一列举了。如果出现线上环境数据库误操作怎么办?有没有后悔药?答案是有的,请各位看官仔细往下看。1.不要用聊天工具发sql语句通常开发人员写好sql语句之后,习惯通过聊天工具,比如:qq、钉钉、或者腾讯通等,发给团队老大或者DBA在线上环境执行。但由于有些聊天工具,对部分特殊字符会自动转义,而且有些消息由于内容太长,会被自动分成多条消息。这样会导致团队老大或者DBA复制出来的sql不一定是正确的。他们需要手动拼接成一条完整的sql,有时甚至需要把转义后的字符替换回以前的特殊字符,无形之中会浪费很多额外的时间。即使最终sql拼接好了,真正执行sql的人,心里一定很虚。所以,强烈建议你把要在线上执行的sql语句用邮件发过去,可以避免使用聊天工具的一些弊端,减少一些误操作的机会。而且有个存档,方便今后有问题的时候回溯原因。很多聊天工具只保留最近7天的历史记录,邮件会保留更久一些。别用聊天工具发sql语句!别用聊天工具发sql语句!别用聊天工具发sql语句!重要的事情说三遍,它真的能减少一些误操作。2.把sql语句压缩成一行有些时候,开发人员写的sql语句很长,使用了各种join和union,而且使用美化工具,将一条sql变成了多行。在复制sql的时候,自己都无法确定sql是否完整。(为了装逼,把自己也坑了,哈哈哈)线上环境有时候需要通过命令行连接数据库,比如:mysql,你把sql语句复制过来后,在命令行界面执行,由于屏幕滚动太快,这时根本无法确定sql是否都执行成功。针对这类问题,强烈建议把sql语句压缩成一行,去掉多余的换行符和空格,可以有效的减少一些误操作。sql压缩工具推荐使用:https://tool.lu/sql/3.操作数据之前先select一下需要特别说明的是:本文的操作数据主要指修改和删除数据。很多时候,由于我们人为失误,把where条件写错了。但没有怎么仔细检查,就把sql语句直接执行了。影响范围小还好,如果影响几万、几十万,甚至几百万行数据,我们可能要哭了。针对这种情况,在操作数据之前,把sql先改成select
2021年3月19日
其他

我用kafka两年踩过的一些非比寻常的坑

大家好,我是苏三,又和大家见面了。前言我的上家公司是做餐饮系统的,每天中午和晚上用餐高峰期,系统的并发量不容小觑。为了保险起见,公司规定各部门都要在吃饭的时间轮流值班,防止出现线上问题时能够及时处理。我当时在后厨显示系统团队,该系统属于订单的下游业务。用户点完菜下单后,订单系统会通过发kafka消息给我们系统,系统读取消息后,做业务逻辑处理,持久化订单和菜品数据,然后展示到划菜客户端。这样厨师就知道哪个订单要做哪些菜,有些菜做好了,就可以通过该系统出菜。系统自动通知服务员上菜,如果服务员上完菜,修改菜品上菜状态,用户就知道哪些菜已经上了,哪些还没有上。这个系统可以大大提高后厨到用户的效率。事实证明,这一切的关键是消息中间件:kafka,如果它有问题,将会直接影响到后厨显示系统的功能。接下来,我跟大家一起聊聊使用kafka两年时间踩过哪些坑?顺序问题1.
2021年2月21日
其他

java中那些让你傻傻分不清楚的小细节

扩展右上角“设为星标”能第一时间看到好文章大家好,我是苏三,又和大家见面了。祝大家新年快乐,身体健康,财源滚滚,万事如意。最近有篇文章在开源中国上火了,让我挺惊喜的。我以前在上面发表文章,一般只有几个阅读量,稍微好点的有几十,如果被推荐也只有几百。像这种有3.2W阅读的情况,还是头一次遇到,真的活久见。非常感谢源码中国平台,让我的文章可以被更多的人看见。前言最近我们通过sonar静态代码检测,同时配合人工代码review,发现了项目中很多代码问题。除了常规的bug和安全漏洞之外,还有几处方法用法错误,引起了我极大的兴趣。我为什么会对这几个方法这么感兴趣呢?因为它们极具迷惑性,可能会让我们傻傻分不清楚。1.
2021年2月14日
其他

9条消除if...else的锦囊妙计,助你写出更优雅的代码

前言最近在做代码重构,发现了很多代码的烂味道。其他的不多说,今天主要说说那些又臭又长的if...else要如何重构。在介绍更更优雅的编程之前,让我们一起回顾一下,不好的if...else代码一、又臭又长的if...else废话不多说,先看看下面的代码。public
2021年1月3日
其他

文末送书 | 迷茫了,我们到底该不该用lombok?

前言最近上网查资料发现很多人对lombok褒贬不一,引起了我的兴趣,因为我们项目中也在大量使用lombok,大家不同的观点让我也困惑了几天,今天结合我实际的项目经验,说说我的个人建议。随便搜搜就找到了这几篇文章:这些人建议使用
2020年12月23日
其他

explain | 索引优化的这把绝世好剑,你真的会用吗?

前言对于互联网公司来说,随着用户量和数据量的不断增加,慢查询是无法避免的问题。一般情况下如果出现慢查询,意味着接口响应慢、接口超时等问题。如果是高并发的场景,可能会出现数据库连接被占满的情况,直接导致服务不可用。慢查询的确会导致很多问题,我们要如何优化慢查询呢?主要解决办法有:监控sql执行情况,发邮件、短信报警,便于快速识别慢查询sql打开数据库慢查询日志功能简化业务逻辑代码重构、优化异步处理sql优化索引优化其他的办法先不说,后面有机会再单独介绍。今天我重点说说索引优化,因为它是解决慢查询sql问题最有效的手段。如何查看某条sql的索引执行情况呢?没错,在sql前面加上explain关键字,就能够看到它的执行计划,通过执行计划,我们可以清楚的看到表和索引执行的情况,索引有没有执行、索引执行顺序和索引的类型等。索引优化的步骤是:使用explain查看sql执行计划判断哪些索引使用不当优化sql,sql可能需要多次优化才能达到索引使用的最优值既然索引优化的第一步是使用explain,我们先全面的了解一下它。explain介绍先看看mysql的官方文档是怎么描述explain的:EXPLAIN可以使用于
2020年12月7日
其他

让人头痛的大事务问题到底要如何解决?

前言最近有个网友问了我一个问题:系统中大事务问题要如何处理?正好前段时间我在公司处理过这个问题,我们当时由于项目初期时间比较紧张,为了快速完成业务功能,忽略了系统部分性能问题。项目顺利上线后,专门抽了一个迭代的时间去解决大事务问题,目前已经优化完成,并且顺利上线。现给大家总结了一下,我们当时使用的一些解决办法,以便大家被相同问题困扰时,可以参考一下。大事务引发的问题在分享解决办法之前,先看看系统中如果出现大事务可能会引发哪些问题从上图可以看出如果系统中出现大事务时,问题还不小,所以我们在实际项目开发中应该尽量避免大事务的情况。如果我们已有系统中存在大事务问题,该如何解决呢?解决办法少用@Transactional注解大家在实际项目开发中,我们在业务方法加上@Transactional注解开启事务功能,这是非常普遍的做法,它被称为声明式事务。部分代码如下:
2020年11月30日
其他

mybatis日志功能是如何设计的?

引言我们在使用mybatis时,如果出现sql问题,一般会把mybatis配置文件中的logging.level参数改成debug,这样就能在日志中看到某个mapper最终执行sql、入参和影响数据行数。我们拿到sql和入参,手动拼接成完整的sql,然后将该sql在数据库中执行一下,就基本能定位到问题原因。mybatis的日志功能使用起来还是非常方便的,大家有没有想过它是如何设计的呢?从logging目录开始我们先看一下mybatis的logging目录,该目录的功能决定了mybatis使用什么日志工具打印日志。logging目录结构如下:它里面除了jdbc目录,还包含了7个子目录,每一个子目录代表一种日志打印工具,目前支持6种日志打印工具和1种非日志打印工具。我们用一张图来总结一下除了上面的8种日志工具之外,它还抽象出一个Log接口,所有的日志打印工具必须实现该接口,后面可以面向接口编程。定义了LogException异常,该异常是日志功能的专属异常,如果你有看过mybatis其他源码的话,不难发现,其他功能也定义专属异常,比如:DataSourceException等,这是mybatis的惯用手法,主要是为了将异常细粒度的划分,以便更快定位问题。此外,它还定义了LogFactory日志工厂,以便于屏蔽日志工具实例的创建细节,让用户使用起来更简单。如果是你该如何设计这个功能?我们按照上面目录结构的介绍其实已经有一些思路:定义一个Log接口,以便于统一抽象日志功能,这8种日志功能都实现Log接口,并且重写日志打印方法。定义一个LogFactory日志工厂,它会根据我们项目中引入的某个日志打印工具jar包,创建一个具体的日志打印工具实例。看起来,不错。但是,再仔细想想,LogFactory中如何判断项目中引入了某个日志打印工具jar包才创建相应的实例呢?我们第一个想到的可能是用if...else判断不就行了,再想想感觉用if...else不好,7种条件判断太多了,并非优雅的编程。这时候,你会想一些避免太长if...else判断的方法,当然如果你看过我之前写的文章《实战|如何消除又臭又长的if...else判断更优雅的编程?》,可能已经学到了几招,但是mybatis却用了一个新的办法。mybatis是如何设计这个功能的?从Log接口开始它里面抽象了日志打印的5种方法和2种判断方法。再分析LogFactory的代码它里面定义了一个静态的构造器logConstructor,没有用if...else判断,在static代码块中调用了6个tryImplementation方法,该方法会启动一个执行任务去调用了useXXXLogging方法,创建日志打印工具实例。当然tryImplementation方法在执行前会判断构造器logConstructor为空才允许执行任务中的run方法。下一步看看useXXXLogging方法:看到这里,聪明的你可能会有这样的疑问,从上图可以看出mybatis定义了8种useXXXLogging方法,但是在前面的static静态代码块中却只调用了6种,这是为什么?对比后发现:useCustomLogging
2020年11月26日
其他

线程池最佳线程数量到底要如何配置?

一、前言对于从事后端开发的同学来说,线程是必须要使用了,因为使用它可以提升系统的性能。但是,创建线程和销毁线程都是比较耗时的操作,频繁的创建和销毁线程会浪费很多CPU的资源。此外,如果每个任务都创建一个线程去处理,这样线程会越来越多。我们知道每个线程默认情况下占1M的内存空间,如果线程非常多,内存资源将会被耗尽。这时,我们需要线程池去管理线程,不会出现内存资源被耗尽的情况,也不会出现频繁创建和销毁线程的情况,因为它内部是可以复用线程的。二、从实战开始在介绍线程池之前,让我们先看个例子。public
2020年10月28日