我有以下情况:用户可以拥有最大数量的合作伙伴关系。例如- 40.000
问题:如果用户想要添加新的合作伙伴关系,如何更快地检查当前合作伙伴的数量?
解决方案1:使用count(*)语句?
解决方案2:将值存储到单独的用户列中。总是当一个新的伙伴关系需要加入,得到它,然后增加该列?
个人备注:是否有更好的解决方案来检查总行数?
有没有人对时间内的表现有统计数据?我认为,当有有限的行数时,解决方案1会更快。但是如果有多个行,那么使用解决方案2就更有意义了。例如,经过多长时间(行数)解决方案2比1更好?
当然,我更喜欢解决方案1,因为我得到了更多的控制。可能会发生错误,并且解决方案2中的列不会增加。在这种情况下,这个数字是不正确的。
发布于 2022-10-05 21:38:00
我将投票赞成解决方案2(在其他地方保持精确计数)。
这将比COUNT(*)快得多,但是有些事情可能出错。添加/删除合作伙伴关系意味着递增/减少计数器。是否有某种情况不是确切的插入/删除?
计数应该在事务中完成。在“添加”中:
START TRANSACTION;
SELECT p_count FROM Users WHERE user_id = 123 FOR UPDATE;
if >= 40K and close the transaction
INSERT INTO partnerships ...;
UPDATE Users SET p_count = p_count+1 WHERE user_id = 123;
COMMIT;所涉及的开销可能高达10 as。数到40K会慢得多。
发布于 2022-10-05 20:50:54
解决方案2是反正规化的一个例子,它存储一个聚合值,而不是依赖于基本数据。实际上,查询这个非规范化值比计算基本数据更快,甚至对于少量行也是如此。
但它是以维护存储的值为代价的。您必须说明错误,这些错误在上面的评论中已经讨论过了。你怎么知道什么时候有错误?回答:您必须运行count查询,并将其与存储在非规范化列中的值进行比较。
你需要多久核实一次计数?也许在每次更新之后?在这种情况下,验证存储的计数与从基本数据计算实际计数一样昂贵。事实上,成本更高,因为您必须计算并更新用户行。
然后,在需要重新计算计数的频率与只查询存储的计数值的频率之间形成平衡。每次在更新之间查询时,您都可以从节省的成本中获益,如果查询比更新频繁得多,那么您就可以节省很多费用。但是,如果您像查询一样频繁地进行更新,那么您将得不到任何储蓄。
https://stackoverflow.com/questions/73965993
复制相似问题