not in 场景下,下面四个方案哪个是最优解呢?

2023-09-18 15:01:31 +08:00
 ben548
活动有设置精选的需求,设置的数量不限(就是说可能很多个,但是从当下的场景来看一般不超过 2000 ),现在需要从数据库里面分页查询除设置精选外的活动数据,我想了想有几种查询方式,
1 、用 not in 语句:select * from activity where id not in (精选活动 id ) limit offset, pagesize
2 、不用 not in 语句,select * from activity where id > 上一次查询的 id (第一次是 0 ) limit offset, pagesize ,然后将查询结果跟精选活动 id 集合比对,去除在集合内的数据,如果结果条目数小于 pagesize ,则进入下一次查询,直到满足结果条数=pagesize ,退出查询循环并返回结果
3 、将精选活动 id 数据写入 featured 表,用子查询,即 select * from activity where id not in ( select id from featured ) limit offset, pagesize
4 、也是将将精选活动 id 数据写入 featured 表,用联表查询,select * from activity left join featured on activity.id != featured.id limit offset,pagesize

个人感觉方案 1 在数据量不大的情况下,应该是最优方案,但是如果精选活动 id 数据量过大,则方案 1 的 sql 语句可能还不如方案 2 ,方案 3 和方案 4 的比较中,我感觉我更倾向于选择方案 4 ,但是说不出啥原因感觉是一种直觉[捂脸]
所以其实我的结论是数据量小直接方案 1 ,数据量大的话方案 4 比较合适。

方案 3 的执行逻辑是不是本质上和方案 1 差不多?

大家觉得呢?
988 次点击
所在节点    MySQL
2 条回复
msaionyc
2023-09-18 15:39:39 +08:00
add column activity_type tinyint default 1 comment "1.普通 2.精选"
select * from activity where activity_type = 1
ben548
2023-09-18 16:20:13 +08:00
@msaionyc 牛逼,这样做确实不用联表也不用子查询也避免了 not in ,用这个方案了

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

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

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

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

© 2021 V2EX