优化一下SQL,性能提升20倍

最近在大数据平写 Hive SQL 跑离线作业,数据量大概在三千万,有一个离线任务每次执行都要两个小时以上,我感觉太慢了。为什么觉得慢?刨除实现 SQL 逻辑的时间,自测、冒烟测试、上线每次执行一次需要 2h,也就是修改一处 SQL 要经历 6 小时才能看到最终结果。根据我的经验判断不应该耗费这么长时间,于是想着看看能不能改善一下。我先让数据平台的同学帮忙看,由于他们忙没得到结果,于是自己动手优化了一下,优化后的结果还是比较让我吃惊的,因为我并没有使用很复杂高深的手段(主要是减少临时表、减少嵌套查询数),却得到了意向不到的效果。这使我产生许多想法和思考。

优化效果,时间减少 95%,内存减少 80%。

  • 优化前:耗时 2h,内存占用 80G
  • 优化后:耗时 6min,内存占用 16G

领导和程序员

If you used to be a programmer, your life was likely calmer and more panicfree. You had a list of work to do, and each day you’d methodically work down your list, writing code and debugging problems. Prioritizing, planning, and executing your work was straightforward.

如果你曾经是个程序员,你的生活很可能要比现在平静,没有很多让人恐慌的状况需要处理。你有完整的工作清单,上面的每个条目你都能有条不紊的解决,写代码或是调试问题。排优先级、定计划,然后执行你的工作,还是很简单的。

As you moved into leadership, though, you might have noticed that your main mode of work became less predictable and more about firefighting. That is, your job became less proactive and more reactive. The higher up in leadership you go, the more escalations you receive. You are the “finally” clause in a long list of code blocks!

当你在管理岗工作后,你可能慢慢察觉到了,你的工作模式变得不可预测,天天都在救火。你的工作变得被动,更多的是响应别人的诉求。你的岗位越高,这个现象越明显。你成了一堆代号的最终负责人。

(via)

随笔|飞向外太空

好久不见

前段时间,我和实验室的同学开了一次线上会议。我们这届实验室自 22 年年底以来还没怎么聚,大家进入视频会议都有些兴奋。一句“好久不见”点燃了埋藏在心底的情感,“是呀,好久不见了~”。这次会议我印象深刻的有两点。第一个是当我们讨论其中一个主题时,有些同学不怎么发言,远远鼓励大家理性说出自己的观点并表示允许尖锐的声音。她随后解释:“一个积极正向发展的团队,是同时需要温和的声音和尖锐的声音的。尖锐不代表错,而一味地温和可能是在隐藏问题。”,我很赞同她的这个观点,相信好的团队能自己消化问题,形成良性循环。第二个是一个问大家的问题:“工作后你的目标变化了吗?”,大家犹豫了一下,每个人都说了一些,但又好像没有说到重点,我发言时说:“变了一些”,从工作以来我越来越觉得自己之前话有些狂妄和异想天开,在开发中,编程语言是简单的,然而业务是复杂的!即使一个简单的登录认证功能在企业环境里也可能很复杂。


将就,还是改变?雅思!

说来话长。工作中我大多数时候查阅的是中文资料,但有时必须查询英文资料,而我并不能完全顺畅地阅读下去,虽然能理解大约七八成,但遇到生词仍需要查一下。现在的情况是,当我查单词时,思路被打断,就像看电影网速太慢导致画面停顿。于是我考虑了一下,决定做件长期的、有意义的事情——考雅思,解决英语阅读问题,如果国内的工作腻了,也有能力尝试去国外开拓一下视野。我不希望用学校那种填鸭的学习方式,而是以实践和理解为主的学习方式。我已经买了几本书,开始学习将近一周,目前感觉不错。


从摄影学到的

在我买相机的几个月拍了一些照片,起初我在网上看了些教程,学到了些伎俩,但拍出的照片让人满意的不多,一组照片只有几个,有时甚至一个也没有,这不禁让我陷入自我怀疑:是我设备不行还是技术不到家?这种情况直到我开始主动思考相机运作机制和每个参数配置的含义后才有所改善,拍不好、不出片是因为不熟悉工具,还有是部分教程看似有用实则无用。现在,如果一个新手问我怎么学摄影,我会告诉他先把工具用熟,了解每一个配置对画面的影响,通过实践形成对光影和环境处理的认知,最后再学习构图知识。


理性、感性

两周前跟朋友一起出去拍照,我问了他一个问题:“你认为摄影是理性的还是感性的?”,朋友可能也没有思考过这个问题,随口回了我一句:”随性的,喜欢的事物,心里有拍照的冲动就按快门“。我倾向于摄影是理性的,每当我们按下快门心里都会对周围环境做一个判断,然后决定用多大光圈、快门,我们也会主动选择一个角度呈现这个画面,即使当我们希望画面呈现出感性时也是心智做出的一个选择(配置参数、控制画面)。

使用多线程的实践思考

#多线程
image

本文源自一个线上问题引起的思考。诚然多线程是有益的,但使用不当反而会造成系统吞吐能力下降,甚至发生死锁。在使用多线程时我们可能面临下列情况:

  1. 当写的并发代码包含框架类的方法调用,总是可能存在线程安全问题,因为框架在不停升级,我们不能保证它一直线程安全的;
  2. 线程配置不当会引起安全问题,例如:缓存队列溢出、瞬时任务增多导致线程池打满,我们的业务在不断变化,在一个新的上下文环境中,没有人能保证线程配置一直合理;
  3. 多线程让编程更复杂(需要处理更多情况),例如:控制执行顺序、并发访问变量;
  4. 在多线程中进行远程请求容易对下游服务(数据库服务或其他业务服务)造成压力;

通过以上,我们看到在项目中引入一种技术带来的额外风险,有时这种风险不是线性增长而是指数级别,因此从这些角度看应该谨慎使用多线程。好的实践是先寻找其他解决方案,最后再考虑使用多线程,把多线程当作性能扩展的最后一道防线。

如果不用多线程就不存在上述的问题,我们假设使用多线程背景下来总一些实践技巧。

» 阅读全文 · 使用多线程的实践思考

回家的旅程

回家的旅程一波三折。

早上匆忙小区到地铁站后发现忘带身份征了,考虑了一下时间成本又跑了回去拿,后来坐上地铁半个钟头才恢复过来;

本以为坐上高铁就能平安到家了,结果到了又差一点坐过中转高铁站(抢到的是中转车票),幸好有个人买了我正在坐的座位,跟他交谈了几句我意识到再不下车就要坐过站了,随即迅速拿着行李下车,果然出来后没多久车门就“咔”的一声关闭了。

整个回家旅程因为这两个事件折腾的很疲惫,我今年一年也不会忘记这次匆忙的经历。

MySQL 的字符集与排序规则

#MySQL

通俗讲字符集就是字符码的集合,在 MySQL 中字符集的选择影响字符码的存储,字符集选择不好不仅影响存储展示还会有问题,例如乱码。

在业务中常用的字符集是 UTF-8 字符集,mysql 有两种这样的字符集:utf8、utf8mb4,它们的区别如下:

  • utf8: 支持最长 3 Byte 的字符编码,但一部分 UTF-8的 4 Byte 编码不支持,例如 emoji。
  • utf8mb4:支持最长 4 Byte 的字符编码。这是业务中使用最多的字符集,从 MySQL 8.0 开始成为默认字符集。

字符的排序规则(collate):字符在比较、排序时以及大小写敏感的规则。涉及字符比较的操作均与其相关,例如:排序、分组、索引、比较(=、>、<等)。MySQL 中有些字符排序规则是忽略大小写的,例如 utf8mb4_general_ci 排序规则,这种带有 ci 后缀的是大小写不敏感的标志(ci 即 case insensitive 的缩写)。

» 阅读全文 · MySQL 的字符集与排序规则

Java 中使用枚举的正确姿势

#Java

在项目开发中我们经常用到枚举定义常量,例如定义系统中用户的身份类型(ADMIN、USER…)、定义项目启动环境的类型(DEV,PROD…)、某个字段的值的枚举等。往往我们发现在项目里定义枚举类时只是有枚举成员,像下面这样:

public enum Type {
  T1,T2,T3
}

不能说这样不好,只是这样差不多又回到了我们使用类定义静态常量常量。Java 中除了有类(class)这种类型,又实现了枚举(enum)这种类型,说明肯定它独特的用处,不妨我们先回忆下使用类成员定义静态常量和枚举定义常量的区别。

  • 使用类的静态成员定义常量,常量只能有一个固定的值,通常是一个简单的字符串或一个数值。
  • 使用枚举定义常量,实例化枚举后不可变,枚举可以携带多个值,这为常量提供了更多信息。(补充,虽说枚举实例化后不可变,但它的成员变量如果不用 final 修饰,是可变的!)
  • 如果你熟悉枚举的原理,你可以通过类(class)模拟出一个枚举(enum),但通常你需要两个类来完成这个工作,一个类来定义枚举和其成员,另一类完成初始化。而枚举(enum)通过编译消除了这些复杂性,可以轻松实例化对象和定义方法。

通过它们之间的区别,可以看出枚举能为我们的常量提供更多的信息和更加便捷的定义、实例化。那么如何利用好枚举这些特性,如何定义好用(便捷)的枚举呢?

» 阅读全文 · Java 中使用枚举的正确姿势

2022 年总结:积极生活每一天

#年终总结

不平凡的一年过去了,生活是个五味调料罐,喜怒哀里交加,平凡中偶尔跳出惊喜,我相信无论处在什么样的境遇,生活中主动些、积极性会变得更好些。

今年年底终于看到疫结束的希望了,距离 2019 年年底发现新冠整整三年了,“大学有几年,疫情占三年”,我印象最深刻的是大学的网课,老师们猝不及防地适应直播教学,学生们不再去教室上课了,还有各个地方的管控,以至于过年、假期回不来家,后来入职后开始了一个多月的线上办公。疫情期间这段记忆太深刻了,以至于听到放开的消息,心情激动就像工作日给放了个假似的,以后可以大胆和朋友聚餐,愉快地出去转一转了。

这一年有两个重要时间节点,毕业、入职工作;这一年终于有空在北京附近的景点转一转;这一年和老同学重新联系聚餐,也和同届的同伴在北京聚了餐。平安喜乐,充实的 2022 过去了。

» 阅读全文 · 2022 年总结:积极生活每一天

《如何讲好一堂课》笔记

这是在网盘里无意间发现的课程,碰巧近期也打算提高下个人综合能力,于是花了一天多学习了下,总体还不错(挺受益),虽然讲的是“如何讲好一堂课”,但对于日常沟通表达也是适用的,单从信息传达效率的角度讲,“讲课”这种形式更加科学、高效。课程不错,收获颇丰,但我学完后还没来得及实践,只匆匆记下了些要点,留作日后复习回顾。

(题外话)通过学习这个课程我真切地体会到一个优秀老师(具备丰富教学经验 & 专业知识 & Passion )能够对学生产生的影响,他们除了“传道、授业”还能以恰当的方式“解惑”,他们行胜于言,有热情,能够在细节之处打动学生。回顾我的学生时代,有几位令我印象深刻的老师,他们是:倪海武老师、侯春芳老师、牛兴丽老师、李学勇老师。

» 阅读全文 · 《如何讲好一堂课》笔记

“最近发展区” 理论

最近发展区理论 是教育学上的一个概念,它把人理解事物的等级做了区分,使教育者可以使用这个理论评估学生和教学内容,以达到最优的教学效率。最近发展区理论具备一定的普适性,也可以用在日常沟通、会议、汇报、分享等场景中,作为评估用户的方法。

根据 “最近发展区” 理论,可以人把当前具备的知识划分为三个级别:知识舒适区、最近发展区、知识困难区。

  • 知识舒适区:人已有的知识,理解应用这些知识自然且没有压力
  • 最近发展区:人可以根据已有的知识可能达到的知识,通常需要借助外力达到;
  • 知识困难区:知识超过了人能理解的范围,理解应用这些知识困难

如果把我们日常场景分成两类:沟通交流(会议、汇报)、分享教学(分享、讲课),那么:

  • 在沟通交流的活动中,应该尽量在双方的知识舒适区进行交谈、讨论,避免出现知识困难区的词汇、概念;

  • 在分享教学活动中,最应该关注的是受众群体的最近发展区,最近发展区的知识能有利地让受众成长和受到启发。知识的掌握是一个循序渐进的过程,知识的准备需要遵循这样的逻辑与原理,在准备时首先要找到受众群体的上限和下限(受众群体存在差异时要找重叠区),在组织材料时通常由下限逐渐延伸至上限。