MySql MyISAM INSERT缓慢

时间:2013-09-17 19:01:36

标签: mysql sql performance

在mysql表中插入一些数据时出现性能问题。 该表有一堆列,比如DATE,A,B,C,D,E,F,其中DATE,A,B,C,D,E是主键。每天,我在该表中插入70k行(具有不同的日期),此表现在包含1800万行。我用来插入行的方法只是发送70k INSERT查询。

我遇到的问题是查询开始比以前花费更多时间。从几分钟到几个小时。我描述了插页,这是我得到的图表:

每个插入的速度(以秒为单位)与当天插入的数量: Speed of each insert (in sec) vs. Number of insert for that day

一些奇怪的事实:

  1. 大多数查询执行时间不到2毫秒
  2. 慢速查询的速度随着该日期表格中的行数线性增加
  3. 此行为仅发生在晚上,在数据库上发生了一系列进程之后。白天插入很快,周末也是如此
  4. 总体速度不依赖于数据库上正在运行的其他内容,事实上,发生这种情况时,数据库上没有其他任何内容正在运行
  5. 查询中没有任何内容可以解释查询是快还是不快,快速查询与慢查询非常相似,而且从一天到另一天不是同一集。
  6. 行为不会从一天变为另一天。
  7. 知道是什么原因引起的吗?

    **编辑**索引中的列按以下顺序排列:

    DATE NOT NULL,
    DATE NOT NULL,
    VARCHAR (10) NOT NULL,
    VARCHAR (45) NOT NULL,
    VARCHAR (45) NOT NULL,
    VARCHAR (3) NOT NULL,
    VARCHAR (45) NOT NULL,
    DOUBLE NOT NULL,
    VARCHAR (10) NOT NULL,
    VARCHAR (45) NOT NULL,
    VARCHAR (45) NOT NULL,
    VARCHAR (45) NOT NULL,
    

    日期与今天相同,或者留空,双倍总是相同的数字(没有设计此表的线索)

1 个答案:

答案 0 :(得分:3)

简短的解释是,您有一个在一天范围内非增量的索引。非增量索引通常较慢地插入/更新,因为它们通常需要重新平衡索引树,并且在更大程度上需要比增量索引重新平衡。

为了进一步解释这一点 - 假设以下架构:

a (int) | b (varchar)

索引为(a, b)

现在我们插入:

1, 'foo'
2, 'bar'
3, 'baz'

这将非常快,因为索引将附加在每个插入上。现在让我们尝试以下方法:

100, 'foo'
100, 'bar'
100, 'baz'

这不会那么快,因为'bar'需要在'foo'之前插入,而'baz'需要在另一个之间插入2.这通常需要索引重写树以适应,这“重新平衡”行为需要一些时间。重新平衡所涉及的组件越大(在这种情况下,a = 100的子集),它将花费的时间越多。请注意,此重新平衡活动仅会发生更多更广泛,但不一定在每个插入上。这是因为树通常会在叶子内留出一些空间用于扩展。当叶子用完房间时,它知道是时候重新平衡了。

在您的情况下,由于您的索引主要基于当前日期,因此您将在一天的范围内不断重新平衡树。每天都会开始一个新的范围,因此在这一天的范围内开始重新平衡。最初这只涉及一些重新平衡,但随着当天现有条目的范围增加,这将会增加。当你开始新的一天时,周期就会重新开始,这就是你所看到的结果。

这发生在主键上可能会使事情变得更糟,因为不是移动一些索引指针,而是可能需要移动整行数据以适应新条目。 (最后一点假设MyISAM集群是在主键上执行的,这一点到目前为止我还没有得到澄清,尽管单数证据确实似乎支持这一点。例如,请参阅here和{{ 3}}。)