所有: 我有一个表来记录每十分钟在某些维度上的一些请求的数量。这是我的表:
owner_id
如您所见,id是一个自动增量大整数,没有任何特殊含义。 log_time
和bid_num
是维度键,而v_bid_num
和owner_id=10
是要更新的内容。受业务逻辑的限制,我无法在插入数据库之前收集所有数据,即我可能必须在log_time='2015-11-11 11:00:00'
和{{1}}两次插入数据库。由于表可能非常大(数百万行)并且需要不断更新,因此我有两个选择:
从性能的角度来看,我不知道哪个更好。
答案 0 :(得分:1)
评论时间有点长。
如果仅关心插入表格,那么第二个选项通常会更快。在大多数情况下,插入新行比检查重复项和插入/更新方法更快。即使桌子变得非常大,这仍然是正确的。只要索引适合内存,这将保持为真。
但是,数据通常还有其他用途,而不仅仅是放在表格中。对于许多查询目的,没有重复可能会显着帮助查询。如果您按user_id
/ log_time
进行查询(如索引所示),则在查询方面处理重复项应该是微不足道的 - 两行与一行的影响最小,{{1}在两行上占用很少的资源。
(嗯,我想有一个边缘情况,插入带有索引的数十亿行的表将比插入具有10行的表同时检查重复项更慢,因为索引更新将比check-for-duplicates查询。但是,你的用例与这种情况相距甚远,因为你每行只讨论2个重复项。)
答案 1 :(得分:0)
计划A
PRIMARY KEY(id),
UNIQUE(owner_id, log_time)
每个插入必须检查两个密钥是否重复;这会减慢插入速度。
计划B
PRIMARY KEY(id),
INDEX(owner_id, log_time)
这要求您的SELECT
代码执行某种类型的GROUP BY
和聚合。
计划C
PRIMARY KEY(owner_id, log_time)
且没有id
。你为什么还有id
?虽然计划A和B总是插入表格“末尾”的数据(因为AUTO_INCREMENT
),但计划C将有多个“热点”,每owner_id
一个。这没关系。
计划D
INDEX(id),
PRIMARY KEY(owner_id, log_time)
如果不接受Plan C,则Plan D允许您保留id
。不,AUTO_INCREMENT
不一定是PRIMARY KEY
。需要IODKU。
<强>哪些吗
除了Plan B之外的所有需要IODKU(在重复密钥更新时插入)。但我不认为这是一个严重的缺点。
计划C和D可能会提高SELECTs
的效果,特别是如果您选择一个owner_id
。
我更喜欢这个顺序中的计划:C,D,B,A。你根据你能够/不能忍受的限制来选择。