MySQL count where xxx=yyy 这种如何优化?

2016-11-06 08:53:36 +08:00
 t123yh
比如 Online Judge 系统里面有很多道题目,每道题目有很多 submission ,而 submission 有几种结果,比如 Accepted , WrongAnswer ,用 int 存储。
现在如果需要快速找出每道题目的 Accepted 提交数和 Accepted 人数(即 submission 对于 userid 去重),应该如何优化?
5557 次点击
所在节点    MySQL
16 条回复
azh7138m
2016-11-06 09:18:30 +08:00
COUNT(DISTINCT user_id) 不就很好吗?
bazingaterry
2016-11-06 09:59:38 +08:00
单独开一个表记录一下?
t123yh
2016-11-06 11:06:40 +08:00
@azh7138m 这样大量数据的时候不会很慢吗
hxsf
2016-11-06 11:27:38 +08:00
select count 1 group by userid
cjyang1128
2016-11-06 11:59:04 +08:00
这种类型的优化一般都是通过反范式,比如题目表里面单独开一个字段记录 accepted 人数和 accepted 提交数,更新的时候采用 select for update 上行锁进行更新。或者可以用其他的数据库实现这种类似的计数器操作,比如 Redis 或 HBase
latyas
2016-11-06 12:40:58 +08:00
@t123yh
现在的问题是,要多快?现有的速度是否无法接受?
如果还没达到量级建议暂时不要考虑优化问题,良结构的方案都会相对来说慢,但是如果不需要,还是不要放弃良好的结构比较好。

@cjyang1128 计数器场景的话建议不要使用 select for update ,我们在这上面被坑出 shi 来了,不如直接用 REDIS 的 INC 操作。
t123yh
2016-11-06 13:25:09 +08:00
@latyas 以后估计得有几万条吧。。
latyas
2016-11-06 14:19:32 +08:00
几万条都是小数据,没必要优化
iyaozhen
2016-11-06 14:21:55 +08:00
@t123yh 等到了几百万再考虑吧。
azh7138m
2016-11-06 20:35:50 +08:00
@t123yh 讲道理, poj 这么多年也才千万提交,没遇到瓶颈不用提前优化的
ZiLong
2016-11-07 11:12:17 +08:00
@latyas @iyaozhen @azh7138m 我跟 lz 一样感兴趣这个问题,如果我们假设我们现在有了五百万条数据呢
azh7138m
2016-11-07 11:18:57 +08:00
@ZiLong 做张 ac 表,加个缓存。
但这会遇到其他的问题,比如 rejudge 时,要重新统计下,还是要用 submit 表去算,其实也没啥,数据量真的很难多到数据库出现瓶颈
ZiLong
2016-11-07 11:25:41 +08:00
@azh7138m web 应用的瓶颈基本都在数据库上
azh7138m
2016-11-07 11:40:34 +08:00
@ZiLong 真的,你数据库出现瓶颈,是要笑出声的,一般网站哪来那么多用户
cjyang1128
2016-11-07 13:00:08 +08:00
@latyas 是不是导致了死锁。。
latyas
2016-11-15 10:51:05 +08:00
@cjyang1128 是的,如果 select for update 语句放在一个比较大的事务里,经常会发生死锁 /

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

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

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

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

© 2021 V2EX