【问题标题】:mysql insert vs update performancemysql插入与更新性能
【发布时间】:2015-11-28 12:31:44
【问题描述】:

全部: 我有一个表格,每十分钟记录一些维度上的一些请求数。这是我的桌子:

    CREATE TABLE IF NOT EXISTS `mydb`.`realtime_bid_traffic` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '',
  `owner_id` BIGINT(20) NOT NULL COMMENT '',
  `log_time` DATETIME NOT NULL COMMENT '',
  `bid_num` BIGINT(10) NOT NULL DEFAULT 0 COMMENT '',
  `v_bid_num` BIGINT(10) NOT NULL DEFAULT 0 COMMENT '',
  PRIMARY KEY (`id`)  COMMENT '',
  UNIQUE INDEX `dim_key` USING BTREE (`owner_id` ASC, `log_time` ASC)  COMMENT '')
ENGINE = InnoDB;

如您所见,id 是一个自增的大整数,没有任何特殊含义。 owner_idlog_time 是维度键,而 bid_numv_bid_num 是要更新的内容。受限于业务逻辑,我不可能在插入数据库之前收集所有数据,即我可能必须将owner_id=10log_time='2015-11-11 11:00:00' 插入数据库两次。由于表可能很大(数百万行)并且需要不断更新,我有两种选择:

  1. 插入或更新重复键。这样对每个维度 只有一行,但它涉及更新,为了 提高性能我为 owner_id 和 日志时间。
  2. 只需插入即可。在这种情况下,我将删除唯一键 owner_id 和 log_time 并插入数据库。由于 id 是 主键它永远不会重复,但它可能会增加表行 显着。

从性能的角度来看,我不知道哪个可能更好。

【问题讨论】:

    标签: mysql sql database-performance


    【解决方案1】:

    评论有点长。

    如果您关心插入到表中,那么第二个选项通常更快。在大多数情况下,插入新行比检查重复和插入/更新方法更快。即使表格变得非常大,这仍然是正确的。只要索引适合内存,这将保持正确。

    但是,数据通常还有其他用途,而不仅仅是放入表中。对于许多查询目的,没有重复项可能对查询有很大帮助。如果您通过user_id/log_time 进行查询(如索引所建议的那样),那么在查询端处理重复项应该是微不足道的——两行与一行的影响最小,order by id desc limit 1 占用的资源很少两行。

    (嗯,我想有一种极端情况,在检查重复项时插入具有数十亿行的带索引的表会比插入具有 10 行的表慢,因为索引更新会比check-for-duplicates 查询。但是,您的用例与这种情况相去甚远,因为您只谈论每行 2 个重复项。)

    【讨论】:

    • " 在几乎所有情况下,插入新行都比检查重复和插入/更新方法更快。" -- 如果检查重复导致更新非索引字段,这可能不会像插入时那样更新索引,因为不需要更新索引。
    • @HannoBinder 。 . .这是一个好点;但是,仅插入方法不需要索引。由于其他原因,它可能是可取的,但插入不需要。
    【解决方案2】:

    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)
    

    如果 C 计划不可接受,D 计划让您保留id。不,AUTO_INCREMENT 不一定是PRIMARY KEY。需要 IODKU。

    哪个?

    除计划 B 之外的所有项目都需要 IODKU(重复密钥更新时插入)。但我不认为这是一个严重的缺点。

    计划 C 和 D 可能会提高 SELECTs 的性能,特别是如果您选择了一个 owner_id

    我更喜欢按以下顺序排列的计划:C、D、B、A。您可以根据您可以/不能忍受的限制来选择。

    【讨论】:

      猜你喜欢
      • 2011-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-27
      • 2016-12-10
      相关资源
      最近更新 更多