不知道大家有没有遇到过一个 sql 连了 7,8 张表

2017-03-04 13:32:59 +08:00
 chaleaoch
在实际的生产环境中,这样会带来很大的效率问题吗?
昨天面试一个大兄弟,单张表只有 7--8 万的记录.连 7,8 张表查询,需要 7--8 秒.我表示很差异.

当然了目前我所遇到过的最大连表只连三张,单表数据也不是很大.大概是一张几千,另一张几百万的样子.

不过很快就查出来了.
4276 次点击
所在节点    数据库
86 条回复
shijingshijing
2017-03-04 17:28:26 +08:00
join 太多自己都觉得麻烦,不过对于这种一个 associate 表,专门负责各个 index 关联的,除了 join ,再就是分解成子查询了,还有其他方法么?我也很想知道。

#r13 @jarlyyn 你们是一条记录主键,关联这么多表的各条记录的 id ,这样实现的吧。
我有一个问题是,如果要对这一条记录进行操作,是不是要分解为多个子查询?

举个例子,我有一个功能是显示用户的累计消费金额。如果用户对一个订单的某个商品进行了退款操作,我要更新用户的累计消费金额,就得在退款的同时,更新这个关联表,然后通过关联表,查询对应的用户 id ,更新用户的累计消费金额。很麻烦,但是感觉也没有其他很好的办法。你们是怎么做的?

还有就是这个累计金额,你们是在用户表里面单独定义了一个字段,还是每次都重新查表计算生成?我们是单独定义了一个字段,因为这个累计金额会很频繁的用到,比如用户登录之后提示,用户每次打开用户信息页面等等,每次都通过查询计算生成的话,感觉会占很大的开销。但是这样做的话,可能会有字段存储的值与实际值不一致的潜在风险,比如用户退货的时候需要更新这个字段,用户在降价之后申请价格保护也会更新这个字段,用户下新的订单会增加这个字段,我们现在是封装了一个函数,业务完成后自动 update ,目前业务逻辑梳理的还算是比较清晰,没有出过问题。但是如果以后有新手接手,忘记添加这一个操作,就有可能造成不匹配,所以一直想问问同行这种情况到底怎么处理算是 best practice 。
chaleaoch
2017-03-04 17:41:37 +08:00
@dallaslu
因为是面试别人的时候聊到这里了.所以我也不知道具体的 sql 是什么.
crist
2017-03-04 17:50:57 +08:00
连表一时爽,全服火葬场
Infernalzero
2017-03-04 18:19:36 +08:00
大致就是两种方法,拆分查询或者宽表冗余字段,拿空间换时间,后者只适用于一致性要求不是很高的场景
系统做大了以后 join 和 count 是两种最大最常见的隐患,所以看阿里的规范里是限制了最多 3 表 join
tumbzzc
2017-03-04 18:25:53 +08:00
在 hive 跑数据才爽。。。
jarlyyn
2017-03-04 18:44:11 +08:00
@shijingshijing

我们的业务压根就不是电商,不算什么 best practice

计算金额 /库存的都记录所有 balance 信息。

就是每一天变动的初始金额,变动值,结束金额,操作相关记录,时间。

然后做一个缓存表,也就是是实际使用的库存 /积分 /现金值。

按你的问题来说,信息错就错,无所谓。由于每一条记录都是有独立记录初始值的。

一旦有问题是可以事后找出来的。有需要的话可以另外跑个进程定时去核查。

有问题不可怕,谁的代码还没点问题,出了问题查不出才可怕。
sobigfish
2017-03-04 18:59:32 +08:00
chaleaoch
2017-03-04 19:06:18 +08:00
@sobigfish
我不是 dba 也不是自身的后端开发.
不过之前曾经看过一本书上说,视图更多的是一种权限控制和简化 sql 的作用.这是视图存在的意义.并不是说,因为视图可以提升 sql 的查询效率.
chaleaoch
2017-03-04 19:10:01 +08:00
@Infernalzero
大侠,请教下.
拆分查询 是指讲一次查询分成多次(例如两次),然后在程序里面将这两次查询出来的结果在合并到一起.
宽表冗余 就是没有关联关系,反范式设计.

是这个意思不?

另,join 和 count 是两种最大最常见的隐患.
join 的隐患应该就是本楼出现的情况.没明白 count 是啥意思?

所以看阿里的规范里是限制了最多 3 表 join
这个是怎么做到的?
eyp82
2017-03-04 19:23:58 +08:00
MySQL 之类的数据库这么搞有很大问题, 互联网业务几乎没这么玩的.
不过传统的企业软件 ERP 什么的, 用 Oracle 数据库, 确实有类似的情况, 不过那也是开发人员懒, 把数据库当万能来用了.
Oracle 多表 join 虽然表现比 MySQL 强太多, 但也最好别这么玩, 很容易成为 top sql.
Infernalzero
2017-03-04 19:49:34 +08:00
@chaleaoch
是这样没错
怎么做到的?靠规范啊
chaleaoch
2017-03-04 19:52:19 +08:00
@eyp82 是的,我面试那哥们做的就是 erp.
大侠,估计解决方案也就两个了(#24)了吧?
还有其他方案吗?

(因为我下分工作也是做 erp...所以比较关心.)
Infernalzero
2017-03-04 19:53:53 +08:00
另外除了人为规范以外,这个也可以做到系统里的,比如发布系统或者 review 系统中对提交的代码做这类检查,如果违反了规范就不允许 push 。这个其实也可以在运行时进行检查,不过不推荐,影响了执行效率,还是编译前检查比较合理,而且至少 TDDL 里默认没有限制
ivvei
2017-03-04 19:54:07 +08:00
Databases are born to join.
chaleaoch
2017-03-04 20:01:24 +08:00
@ivvei
啥意思?
dexterzzz
2017-03-04 20:06:01 +08:00
搞 BI 用列存储数据库,不用在乎多少 join
bonfy
2017-03-04 21:04:31 +08:00
连几十个 表的都见过...各种 join...
LEFT
2017-03-04 21:23:38 +08:00
我们厂光商品就涉及 6 张表了
killerv
2017-03-04 21:32:34 +08:00
遇到过, 8 个 join ,一个子查询,最大的一个是十几万的表,其他表都是几十条,耗时 30s ,能写出这样的 sql 我也是服
fxxkgw
2017-03-04 21:40:14 +08:00
表示上周一直在做各种 join on as 操作。。。头都大了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/344855

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX