流量一大用SQL是不能用JOIN的
我们当时的场景是,一张销售商品表(SPU维度),一张商品SKU表,和一张活动表,我当时做了三表关联,全部都用到索引的,期初跑的很好,SQL都执行的很快,直到某一天,流量陡增后,连接池里的数据库连接突然突然不够用了,导致所有其他的接口的响应速度都变很慢。
整个系统不可用了。
每个业务请求,只要涉及到读取数据库的,响应时间都是超长的,因为一直拿不到数据库连接。
后来,我的解决方案是,用单表查询,活动表/商品表/SKU表,各读一次,就再也没有发生过数据库连接不够用了。为什么?
为啥多读几次表反而更加快了? join语句只执行一次反而慢了?
关键原因在于:当有请求到来的时候,执行的线程拿到数据库连接干活的时候,需要用最快的速度,把数据库连接放回到连接池里去,其他线程才能拿到。
而join它要去读取三棵B+树,无论你sql执行效率多高,都没用的,因为耗时一定比读取一棵B+树慢的。举例:
线程A执行JOIN,0.2秒
线程B执行JOIN,0.2秒
线程C执行JOIN,0.2秒
并发一来,每个线程都要单独占用一个数据库连接0.2秒了,好了,流量一大,占用大量连接,而之前的连接又没有释放,那故障就马上发生了。
而单表的:
线程A单表0.01秒
线程B单表0.01秒
线程C单表0.01秒
也是并发,但是线程占用数据库连接的时间短,马上释放,其他线程等一会就能拿到数据库连接了。
因此,后续有面试官问你关于SQL JOIN的问题,你可以这么回答:
看并发,如果流量不大数据量不大,用join没问题,哪怕join 10张表都没问题的。但是流量一大,由于要跨多棵B+树读取数据,占用数据库连接会变长,连接池一下子就没有了,系统响应就开始变慢。
