我有一张大约1亿行的表,要复制更改以添加索引。我不是很在意创建新表的时间,但是如果在插入任何数据之前先更改表或先插入数据然后再添加索引,创建的索引会更有效吗?
我有一张大约1亿行的表,要复制更改以添加索引。我不是很在意创建新表的时间,但是如果在插入任何数据之前先更改表或先插入数据然后再添加索引,创建的索引会更有效吗?
Answers:
在数据插入之后创建索引是更有效的方法(甚至经常建议在批量导入之前和导入之后重新创建索引以删除索引)。
语法示例(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
插入然后创建索引-大约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
创建索引,然后插入-大约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))
总结更多的时间。