在mysql表中插入一些数据时出现性能问题。 该表有一堆列,比如DATE,A,B,C,D,E,F,其中DATE,A,B,C,D,E是主键。每天,我在该表中插入70k行(具有不同的日期),此表现在包含1800万行。我用来插入行的方法只是发送70k INSERT查询。
我遇到的问题是查询开始比以前花费更多时间。从几分钟到几个小时。我描述了插页,这是我得到的图表:
每个插入的速度(以秒为单位)与当天插入的数量:
一些奇怪的事实:
知道是什么原因引起的吗?
**编辑**索引中的列按以下顺序排列:
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,
日期与今天相同,或者留空,双倍总是相同的数字(没有设计此表的线索)
答案 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}}。)