mysql插入vs更新性能

时间:2015-11-13 11:47:02

标签: mysql sql database-performance

所有: 我有一个表来记录每十分钟在某些维度上的一些请求的数量。这是我的表:

owner_id

如您所见,id是一个自动增量大整数,没有任何特殊含义。 log_timebid_num是维度键,而v_bid_numowner_id=10是要更新的内容。受业务逻辑的限制,我无法在插入数据库之前收集所有数据,即我可能必须在log_time='2015-11-11 11:00:00'和{{1}}两次插入数据库。由于表可能非常大(数百万行)并且需要不断更新,因此我有两个选择:

  1. 在重复键上插入或更新。以这种方式为每个维度 只有一行,但它涉及更新,以便 提高性能我为owner_id和。建立了唯一的密钥 log_time。
  2. 只需插入即可。在这种情况下,我将删除唯一键 owner_id和log_time,只需插入数据库即可。因为id是 它永远不会复制的主键,但它可能会增加表行 显著。
  3. 从性能的角度来看,我不知道哪个更好。

2 个答案:

答案 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。你根据你能够/不能忍受的限制来选择。