Dre*_*ens 73 mysql database indexing
我有一个大约100M行的表,我将要复制以更改,添加索引.我不是很关心创建新表所花费的时间,但是如果我在插入任何数据之前更改表或首先插入数据然后添加索引,那么创建的索引会更有效吗?
val*_*zka 95
在数据插入后创建索引是一种更有效的方法(甚至经常建议在批量导入之前和导入后重新创建索引时删除索引).
Syntetic示例(PostgreSQL 9.1,慢速开发机器,一百万行):
CREATE TABLE test1(id serial, x integer);
INSERT INTO test1(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 7816.561 ms
CREATE INDEX test1_x ON test1 (x);
-- Time: 4183.614 ms
Run Code Online (Sandbox Code Playgroud)
插入然后创建索引 - 大约12秒
CREATE TABLE test2(id serial, x integer);
CREATE INDEX test2_x ON test2 (x);
-- Time: 2.315 ms
INSERT INTO test2(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 25399.460 ms
Run Code Online (Sandbox Code Playgroud)
创建索引然后插入 - 大约25.5秒(慢两倍以上)
这对于这个问题并不重要,因为:
O(n*log(N))
更长(其中n
添加了行)。因为树生成时间是O(N*log(N))
如果您将其拆分为旧数据和新数据,您O((X+n)*log(N))
可以简单地将其转换为O(X*log(N) + n*log(N))
这种格式,并且以这种格式您可以简单地看到您将等待额外的内容。n
新行)都会获得更长的插入时间,O(log(N))
在添加新元素后重新生成树的结构所需的时间(新行的索引列,因为索引已经存在并且添加了新行,则必须重新生成索引以平衡)结构,此成本O(log(P))
其中P
是索引幂[索引中的元素])。你有n
新的行,最后你有n * O(log(N))
总结O(n*log(N))
额外的时间。