where in 和 where not in 怎么优化

2021-05-22 21:36:52 +08:00
 awanganddong

1.业务场景,在用户表查询这个用户的好友。 2.业务场景,查出除黑名单的所有人。

好友和黑名单人数都在几千人。

1879 次点击
所在节点    编程
14 条回复
yeqizhang
2021-05-22 21:39:35 +08:00
我觉得黑名单是好友中加了状态的一类
xy90321
2021-05-22 21:50:23 +08:00
SQL 层面感觉没什么好优化的
如果你想减轻 DB 压力,就把除去黑名单联系人的逻辑搬去 BL 做
如果你想减轻服务器压力,那就搬去客户端做
yitingbai
2021-05-22 22:00:58 +08:00
我也在头疼 in 的问题, 但是又没有别的好办法, 只能 in
nine
2021-05-22 22:31:21 +08:00
好友和黑名单不是在中间表里存着的么?为什么要 in 呢?
awanganddong
2021-05-22 22:43:07 +08:00
就比如我想从用户表里边匹配合适的用户,这时候就要剔除黑名单等不符合用户。
而且不单单这两个地方,
许多地方都需要 in
BeautifulSoap
2021-05-22 22:57:39 +08:00
你好友黑名单数据难道是放在数据库之外的只能先获得好友 id 列表,然后 where in ?
还是说表设计有问题?一般我觉得好友关系和黑名单信息是分开放在两个表里(或者单个表里有个字段标注是不是拉黑),想获得没有黑名单用户的信息的话,直接从好友那个表 join 不就行了,也用不到 in 的操作啊
还有一点是你真的需要一次性搜出几千个用户数据吗?做数据分析还能理解,如果拿来做网页或给 app 提供数据,你根本用不着直接把所有数据都一次性搜出来吧
512357301
2021-05-22 23:14:38 +08:00
@awanganddong 有没有测试过 left join ?
根据你的描述,好友表是包含黑名单的数据的,那最快的方法就是好友表再加个黑名单字段用来标识出黑名单状态,这样直接 where 约束就行。
在没有黑名单字段的前提下,可以考虑 left join,左连接以后,再在 where 里约束右表等于 null 那部分,这样左表里剩下的数据就是所需的了。
select a.id from a --好友表
left join b on a.id=b.id --黑名单表
where b.id is null
我是数据出身,没想过用 java 或者 php 之类的编程语言会不会更快,单纯用 sql 实现的话也就是这个思路了,我个人比较抵触在 in 里套子查询
awanganddong
2021-05-22 23:42:22 +08:00
比如现在要查询其他在线用户。
那我首先获取到这个用户的黑名单 uidArr,
然后拿着这个 uidArr 去 where not in 去剔除这些用户(对于这个用户黑名单可能有几千的数据)

----------------
用户会话列表,客户端是把聊天用户的唯一标识给我,
然后我去 where in 这些标识 去获取这些列表
BeautifulSoap
2021-05-23 00:26:56 +08:00
@awanganddong 把你相关表结构说一下,光你这文字描述根本猜不出来你表怎么建的,搞不懂你为什么需要先查到用户的黑名单 id 数组

你的 好友关系表 的结构难道是 user_id friend_id 两个字段?然后黑名单则是通过 string 格式的数组直接保存在 用户信息表 的一个字段里?
awanganddong
2021-05-23 09:51:35 +08:00
不知道你用过陌陌没有,陌陌有附近的人。然后我把这个用户加黑名单了,那在附近的人这个列表里边就不能出现,类似这样的业务需求。
一张 user 表 id
一张 user_blacklist 表 id uid
c6h6benzene
2021-05-23 12:31:30 +08:00
@awanganddong blacklist 表里面的 uid 就是被黑名单那个用户的 id 吗?

如果“附近的人”也是一张表的话(里面有 id ),那就用 uid left join 这张表的 id,取 join 结果为 null 的好了。

另外也可以试试 exists
awanganddong
2021-05-23 19:25:36 +08:00
单纯靠 mysql 已经解决不了这个问题了


exists 和 union all 都用了 , 好不如原来的 where in 的性能
uselessVisitor
2021-05-23 20:35:47 +08:00
直接用代码实现会不会快一些捏?
awanganddong
2021-05-24 21:46:03 +08:00
想到一种思路

where in ID 分段,然后我起多个线程或者多个携程并发请求。

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

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

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

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

© 2021 V2EX