跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 为什么很多人连基础的 SQL 都写不好,却开口闭口就是缓存架构分布式?
未分類
3 9 月 2021

为什么很多人连基础的 SQL 都写不好,却开口闭口就是缓存架构分布式?

为什么很多人连基础的 SQL 都写不好,却开口闭口就是缓存架构分布式?

資深大佬 : wh469012917 17

说下情况,我们公司同个部门的好几个同事,连个基础的 SQL 都写不好,代码中一堆数据库 N+1 的问题,连个 WHERE IN 查询都不会用,涉及到批量查询,都是遍历然后一条条的去跑 SQL,同一个方法重复查询了好几次,数据库设计更是不行,外键都是用逗号分隔拼接成字符串,然后保存到主表上。

正因为 SQL 写的烂,所以接口性能很差劲,但是他们好像都不在意这些 IO 方面的优化,整天在想着怎么优化语言性能,比如反射、JSON 序列化、语言基础库的性能;要么就是上集群、加缓存,然后又没有任何设计模式,直接业务代码中强硬加入缓存读写,就算是缓存也是先从缓存读出数据,然后遍历一条条去数据库再查出来,性能更差了

其实整体项目量不大,好好写好 SQL,基本上能搞定 90% 的性能问题了,大部分的开发经验也都好几年了,不至于这种基础知识点不懂,可为啥就是不重视 SQL 性能

大佬有話說 (100)

  • 資深大佬 : infun

    可能是培训的

  • 資深大佬 : charlie21

    方便搞大清洗,具体请 v 站搜大清洗

  • 資深大佬 : felixcode

    他们理解的没有好好写 SQL,只是认为自己把逻辑和负载都放程序代码里了,SQL 不值得优化。
    却没意识到 SQL 能力的孱弱已经是瓶颈。

  • 主 資深大佬 : wh469012917

    甚至在优化 json 序列化、网络传输包、语言反射等性能,但是代码中 sql 查询一大堆的 n+1,那些优化等半死,才提升了几十毫秒的性能,大头全被 sql 占去了

  • 資深大佬 : palfortime

    可能考虑以后量大的时候能够容易扩展? in 的值多了也不走索引。

  • 主 資深大佬 : wh469012917

    @infun 也不至于,都是工作了四五年了,再怎么培训的也不至于这么不行,其他缓存队列分布式,说的头头是道

  • 主 資深大佬 : wh469012917

    @palfortime 就算 in 能这样解释,那 n+1 呢?这个可是妥妥的拉性能的查询

  • 資深大佬 : Acoffice

    因为公司不在乎,领导不在乎,拿钱干活,至于活干的好不好,没人在乎啊!
    最重要的是 很多人只是来挣工资的,至于自己的技术,凑合就行啊!
    —
    还有的是公司文化,得 有人造锅,有人甩锅,有人接锅 才能形成闭环,利益最大化!

  • 主 資深大佬 : wh469012917

    @Acoffice 我倒是更认同你这个说法

  • 資深大佬 : GiantHard

    Code Review 的时候提醒一下应该会改吧

  • 資深大佬 : yanzhiling2001

    别说了别说了,感觉都是再说我。
    大佬指点一下该怎么优化 sql,或者 怎么发现 sql 执行时间这个问题。
    写 sql 从来都是随心所欲,拿出来数据就行了的。

  • 資深大佬 : RRRoger

    i cannot agree more

  • 主 資深大佬 : wh469012917

    @GiantHard 木有 code review

  • 資深大佬 : opengps

    能被作为典型培训的教材,普遍都是分布式集群等环境下处理简单业务的模式。模式本身没问题,只是确实让一帮没理解透业务的人充了门面

  • 資深大佬 : wm5d8b

    @wh469012917 培训的是有这种情况,工作多少年都一样,他们完全没有这方面的认知。另外,说的头头是道,不代表实际会用,许多人都是只会背诵

  • 資深大佬 : wangbenjun5

    循环查 sql,确实致命,哈哈,不是懒就是真蠢!!!

  • 資深大佬 : xinJang

    涉及到批量查询,都是遍历然后一条条的去跑 SQL

  • 資深大佬 : xinJang

    @xinJang 这句没看明白。是查出 list 然后批量 update 或 delete ?

  • 主 資深大佬 : wh469012917

    @xinJang 你想多了,举个这个的需求:在一个用户列表里,显示用户发表的动态数量;他们的实现就是先把用户列表取出来,然后遍历这个 userList,然后取其中的用户 ID,再一条条 SQL 去 count 用户的动态数量,在组装到用户实体上

  • 主 資深大佬 : wh469012917

    @wangbenjun5 我有委婉提过这个问题,他们说 JOIN 太难用了

  • 主 資深大佬 : wh469012917

    @opengps 对的,分布式微服务架构,是一把利剑,但其实大部分中小应用都用不到,单体应用一把梭了

  • 主 資深大佬 : wh469012917

    @yanzhiling2001 可以去学习一下 mysql,都说 IO 是 Web 应用的性能瓶颈,而 SQL 查询是 IO 最重的地方,优化一条慢查询,比你做什么集群分布式都好用

  • 資深大佬 : xinJang

    @wh469012917 这种应该直接关联表查询,子查询 count 吧

  • 主 資深大佬 : wh469012917

    @xinJang 对的,关联查询一条 SQL 就能搞定了,按照遍历的方式,列表越长执行的 SQL 数越多

  • 資深大佬 : wangyzj

    会做不如会叫
    叫得好听肯定更容易被喜欢

  • 資深大佬 : xinJang

    @wh469012917 这里我想引申一个问题。就是最近有个项目用得 spring boot,orm 框架是 jpa 。这里关联查询出来的数据,关联表的字段没法映射到实体类,网上没找到好的解决方式,这种有遇过么?

  • 資深大佬 : final7genesis

    @wh469012917 第一次就把系统做好了,没有优化空间,系统上线没问题,然后老板把研发开了,留下几个运维人员

  • 資深大佬 : zhuzhibin

    习惯就好 动不动就分布式、高并发、微服务 我身边也很多这种人,他们可能仅仅是看了一篇文章,就开始吹,各种熟悉 xxx,问起来或者动起手来,就尬住。

  • 資深大佬 : lizhenda

    其实就是不会不重视不想学

  • 主 資深大佬 : wh469012917

    @zhuzhibin 我们每天访问量不大,也就百万级别,而且并发不高,写好 sql 其实可以解决大部分问题了

  • 主 資深大佬 : wh469012917

    @lizhenda 差不多这个意思,学起来不难,就是不想去学,能用就行

  • 資深大佬 : stach

    主说的有道理, 不过单看你举的那个例子, 如果 `用户发表的动态数量` 这个表很大的话 (上千万), 你同事做的并没有问题.

  • 資深大佬 : stach

    更好的做法是, 设计一张独立的用户统计表, 把 `动态数` 存起来, 单独维护, 这样就可以批量查询用户的动态数量了.

  • 資深大佬 : Latin

    同事:你在教我做事啊! (狗头

  • 資深大佬 : offswitch

    @wh469012917 join 确实难用,就你说的这个,list 估计也不大,像 count 可以优化一下,改成读缓存。

  • 資深大佬 : summerLast

    @xinJang @Formula 看看这个注解

  • 資深大佬 : chendy

    因为这种操作更容易让外人觉得自己很厉害,更容易找到吹逼的资本然后找下家
    深耕业务各种优化也可以,但是要注意自己做记录做统计,因为不懂的人真的不知道你在干啥

  • 資深大佬 : thtznet

    国内风气如此,不加点新名词怎么显得高级(华为别骂我)? SQL 用来几十年太成熟了,爆点不好搞出来嘛。

  • 主 資深大佬 : wh469012917

    @stach 我是为了避嫌,所以假设了一个业务场景,而且下文也说了,数量级不大,单表最多也不过 2000w,过早的优化是万恶之源,只要写好 sql,基本上 ok

  • 主 資深大佬 : wh469012917

    @offswitch join 不难用,只是心里害怕罢了;读缓存如何保证数据一致性呢?

  • 主 資深大佬 : wh469012917

    @thtznet 这个倒也是,国内风气确实也不大行,我上一家公司,一个没啥访问量的公司内部系统,都得用上全套的微服务架构

  • 資深大佬 : zxCoder

    正常,我还没毕业呢,找工作看的也都是分布式架构啥的,写 SQL 这种平时自己小项目也不会在意,面试也不怎么问

  • 資深大佬 : MoYi123

    确实,我也碰到过有些人,4 种事务隔离级别倒背如流,写 sql 要把某个数字-1 的时候,要先弄个 redis 锁,select 出来再 update 。

  • 主 資深大佬 : wh469012917

    @zxCoder 不积跬步,无以至千里

  • 資深大佬 : dcoder

    1. 因为精通 SQL 对跳槽, 尤其是互联网高薪的职位, 好处很少
    大家都是面向简历编程 XD
    2. SQL 确实表现力很弱, 很多时候用着别扭. join, 甚至自带的外键什么的, 搞分布式挺忌讳的.
    其实我觉得 SQL 能流行, 就是整个行业之前把科技树点歪了… 这个说来就话长了… 但是从目前大环境看, SQL 用起来方便的时候, 该用还是得认真学, 正确地使用
    3. SQL transaction VS distributed lock (Redis)
    使用在 1 个 db, 1 个 service 时候, SQL transaction 好用
    逻辑稍微复杂点, 跨 db/services 的时候, 还真得用 distributed lock

  • 資深大佬 : jtwor

    中间件工程师。。

  • 資深大佬 : xx6412223

    太多了,
    分布式锁:不管运维,成本,稳定性,就要上 zookeeper 啥的。用 sql 写一个排他锁不会,数据库乐观锁没听过

  • 資深大佬 : nekoyaki

    点进来之前我以为主指的 sql 写不好指的是不用存储过程 /触发器 /各种偏门函数 /复杂 sql 联查,还想说这些邪门歪道到了大数据量的生产环境以后再想优化就是受罪
    结果点进来之后一看,哦连 n+1querys 和 where in 都不会用,那就确实是最基本的能力问题了……

  • 資深大佬 : daguaochengtang

    这就像现在前端原生 js 基础都没搞懂呢,满口都是 vue 源码

  • 資深大佬 : calming

    太畸形了,面试都要问分布式啥的,基本上平时都随便写写业务狂背八股文不就这个下场嘛

  • 資深大佬 : offswitch

    @wh469012917 不是我写不好,这上面的人对 mysql 了解估计还没我深,写 join 很蛋疼,要处理起来太麻烦。

  • 資深大佬 : wxy1991

    你这什么公司啊,我工作 5 、6 年都没见过 n+1 逻辑的代码,连用外键的都少,刚看到帖子的时候我还纳闷 n+1 是什么问题,感觉稍微脑袋正常的人都写不出来这种代码吧,而且像很多公司都是禁止使用外键的。

  • 資深大佬 : jsjjdzg

    惭愧,SQL 写的不太好,有次面试喜欢的公司因为 SQL 不行被 Pass 了 = =

  • 資深大佬 : silk

    @daguaochengtang 毕竟面试只问算法

  • 資深大佬 : jsjjdzg

    自己练习的也少,公司的要求也是 SQL 不准使用复杂 SQL,能业务处理的就业务处理

  • 資深大佬 : xuanbg

    基本功不行的,遇到问题只会照抄。而且不懂得变通,解决问题的手段往往极其拙劣。

  • 主 資深大佬 : wh469012917

    @dcoder sql 手写难受,那用个好用的 orm 可以解决大部分 sql 问题了。就比如 laravel 的 orm,基本上都不用手写 sql 了,但是虽然不用自己写,但是原理还是要懂,至少最简单的 in 查询要会吧

  • 主 資深大佬 : wh469012917

    @calming 面试问不问是一回事,至少自己要懂这些东西吧,sql 算是基本功了

  • 資深大佬 : neoblackcap

    @wh469012917 join 的问题在于你把业务压在数据库层面上了,这个看规模。有的公司倾向于在代码层面上面解决这个问题。用不用 Join 得看情况。因为如果换底层了,count 的方式可能比较好改,join 的方式就不见得那么好改了(比如加缓存或者换数据库存这部分的信息)。

  • 主 資深大佬 : wh469012917

    @wxy1991 多了去了,可能你们也存在 n+1 的问题,只是没发现而已; google 搜索一下 sql n+1,这个在使用 orm 的时候比较经常遇到

  • 主 資深大佬 : wh469012917

    @neoblackcap 这样说其实也对,也可以把 join 拆出来,分开查询也可以,但是 n+1 以及 in 查询,这些算是基本功了

  • 主 資深大佬 : wh469012917

    @daguaochengtang 正常,瞎说又不用有什么成本

  • 資深大佬 : kemistep

    sql 写的好不好,让他们写个次日留存,第 2 日留存,第 3 日留存,就知道能力了;

  • 資深大佬 : jtwor

    in 很多都是临时表查出 id 然后再用 id 去 in 查询这样就走 range 了好像比 index 还快。join 要看分库分表决策吧。确实现在很多都用 orm,直接弱化很多人的 sql 能力。

  • 主 資深大佬 : wh469012917

    @jtwor 对,这样也确实比较建议;但是奈何不会啊,都是遍历这个 id list,然后一条条 where id = ? 这样去查询,妥妥的拉低性能

  • 資深大佬 : ipwx

    @wh469012917 所以你可以问问你的同事,有没有听说过临时表 TEMPORARY TABLE,知不知道 mysql temporary table ON HEAP 是内存表很快。
    —-
    你看,如果不知道临时表这个功能,那你除了 for loop 还有啥办法?当年我不知道临时表的时候,我为了不那么愚蠢的 for loop,最开始我是给 id 切成一个 batch 一个 batch 然后 for loop 的。为了能用 prepared statement 我还强行填满最后一个 batch 然后靠 null 来区分是不是真的有数据。。。

  • 資深大佬 : lithiumii

    给他们发个只连生产数据库的 Tableau,让他们做各种统计报表,一个月下来保证个个都是随手三百行 sql 的大佬(于此同时数据库被平均时长半小时的慢查询淹没,用户没一个能在上班时间使用的

  • 資深大佬 : ipwx

    @wh469012917 你别笑。当年我很在乎性能,可是不知道 temporary table 就是不知道。我都用上 batch + null 判断来“想办法优化性能了”(大概确实能优化一点吧)

  • 主 資深大佬 : wh469012917

    @lithiumii 线上很多接口超时的,都是 sql 查询太多了

  • 資深大佬 : roundgis

    n+1 要看情況,如果可以命中 cache
    還好了
    特別是那種 select by id 的簡單查詢

  • 資深大佬 : pocarisweat

    类似 FaceBook 到今天都在大量使用自己魔改的 PHP,为什么不用 Go 重写呢?说明 FaceBook 的技术眼界已经被 Bilibili 吊打了

  • 主 資深大佬 : wh469012917

    @roundgis 对的,如果有 cache 确实还算 ok,但是关键没有 cache 也这么搞

  • 資深大佬 : dcoder

    @wh469012917 以前写 Django 时用 ORM 很多. 后来写 Go 多了, 都是直接写 SQL 了. 感觉各有个的好.

  • 主 資深大佬 : wh469012917

    @dcoder 嗯对的,没有哪个更好,选个合适的即可

  • 資深大佬 : CodeCodeStudy

    面向面试编程,现在的面试动不动就是分布式、大数据什么的,多吹一吹这些东西能拿高工资,因为面试官特别是当了管理的面试官,大多都是杂而不精,每个东西都懂一点,所以叫他们深入 SQL 优化,他们也不知道,更不知道怎么去问人,通常都是笼统地问怎么优化数据库

  • 資深大佬 : muzuiget

    开讲有话:面试造航母,工作拧螺丝。

  • 主 資深大佬 : wh469012917

    @CodeCodeStudy 话这么说,但是开发自己至少要懂吧,这些算是基本功了

  • 資深大佬 : sagaxu

    我司平台架构组大佬,搭建的配 key value 置中心,key 在 db 里面是没有索引的,每次落到 db 都是全表遍历

  • 資深大佬 : JudyHal

    一般只有写 Java 的人才会有这个特点

  • 資深大佬 : qinghou

    统计慢查询,挂在名字上,自动就能学会优化 SQL 。
    缓存队列分布式如果真能说的“头头是道”,mysql+SQL 相对来说简单很多。

  • 資深大佬 : wangkun025

    以为是说我

  • 資深大佬 : xz410236056

    “正因为 SQL 写的烂,所以接口性能很差劲,但是他们好像都不在意这些 IO 方面的优化”
    虽然他们很垃圾。但是这些工作不是 DBA 的事儿吗

  • 資深大佬 : xz410236056

    @felixcode 这么看平时是没有做性能分析的,用分析工具很容易看到哪里是瓶颈

  • 資深大佬 : vjnjc

    占问一道 sql 面试题,想出,但设计不好。。

  • 資深大佬 : play78

    @lithiumii 确实,以前感觉 orm 特别好用,不用写 sql 。直到我负责公司运营数据后。各种按月按年各种汇总数据分析。才感觉写 sql 是最舒服的。徒手 100 行 sql,返回结果可能就是 12 个月的平均销量,12 个数值而已。如果用 orm 那种方式,带宽、CPU 都跑满。哈哈哈。

  • 資深大佬 : chnyuwen

    @JudyHal 这都能带上一个群体我是没想到的

  • 資深大佬 : ArJun

    反驳一下主吧。技术不值钱,业务才是老板在乎的,换句话说有多少用户,对于中小公司只要不影响收钱上级一般不会太多干涉

  • 資深大佬 : auh

    不想靠实力,当个混子又不犯法。

  • 資深大佬 : xipushi

    做功能的时候,不可能把所有未来出现的情况都考虑到,当时能用就行了。有问题再慢慢优化。

  • 資深大佬 : cxshun

    @sagaxu 这种大佬还留着吗?数据再多点,到了十万级别就够它喝一壶了

  • 資深大佬 : Leviathann

    @ipwx 我们现在也是,不过是写了个工具方法,底层就是分批后调用 jpa 的 find in,不是裸拼 sql 的话其实还挺方便的

  • 資深大佬 : Eytoyes

    @xz410236056 #82 现在大佬们都讲究全栈(狗头

  • 主 資深大佬 : wh469012917

    @xz410236056 DBA 有说啊,说你们数据库负载大,他就以为是访问量大,得加配置

  • 資深大佬 : Leviathann

    看到 hibernate 的各种概念就头大,稍微复杂的查询我宁愿 jdbc 拼 sql

  • 資深大佬 : CodeCodeStudy

    @wh469012917 #77 我是说产生这种情况的原因,我并不认同整天吹分布式什么的

  • 資深大佬 : gamexg

    看情况
    如果不存在性能问题,那么写的会很随意,怎么方便怎么来。
    聊起来,聊缓存等挺正常。
    但是如果真的碰到性能问题,
    对明显的 sql 语句问题不会优化,那就真的有问题了。

  • 主 資深大佬 : wh469012917

    @gamexg 很多接口因为 sql 查询太多,都超时了

  • 資深大佬 : tairan2006

    写 SQL 是基本功

  • 資深大佬 : lithiumii

    @play78 其实我是在讽刺另一种情况,会手写长 sql 瞎 join 的人太多,把生产数据库拖累了,我们踩过这个坑,后来就把给数据分析们的数据库分离了,爱咋写咋写去

  • 資深大佬 : Actrace

    老老实实把基础 SQL 写好了就行了。
    存储过程,触发器,计划任务,都是坑。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具