首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

怎么快速插入上亿条记录

2013-09-07 
如何快速插入上亿条记录insert into t2(id,c2,c3)select (id,c2,c3)from tSQL语句简单, 但此表(t) 非常庞

如何快速插入上亿条记录
insert into t2
(id,c2,c3)
select 
(id,c2,c3)
from t

SQL语句简单, 但此表(t) 非常庞大, 记录条数是2亿多条, 查看这个表的大小有七十多个GB。

试着一次性插入, 结果导致了 tempdb 的被爆满, 提示空间不够(tempdb目前大小10GB左右)。 
不过其它几千万数据的插入, 不出错也是并不快, 22534250条的数据插入也执行了20062秒。

后来写了个存储过程, 分批插入, 每次插入1百万条左右。 速度还可以吧。

看看网上的介绍, Orcle 有分批插入的功能, 有点好奇地问问:
SQL Server 有没有类似的功能, 或者说简单点的办法来实现呢?

快速插入?sqlserver
[解决办法]
用bcp命令
[解决办法]
2亿的记录,不是小数据量了。分批次,每次几十万笔
若无特殊需求,将日志设为SIMPLE
[解决办法]
表要做分区,然后才有“可能”并行插入,如果你要借助tempdb,那它的大小和IO要满足要求。尽量减少文件因大小不足而增长,如果T和T2都做了分区,那用switch分区切换,听说可以秒杀百万级别的数据,不过具体还是要测试。
[解决办法]
--#1.手工处理:BCP导出,然后再BCP导入。
--#2.快照复制:如果是一次性的,建议用快照复制,做一下同步即可。
[解决办法]
同数据库,每10万或百万执行一次,应该是最快的了,日志设为简单
因为慢在日志文件的生成上
[解决办法]
在表已经存在的情况下,构建分区表,通过删除主键约束,重建主键约束,同时按照分区架构来建立聚集索引。当然,如果表本来就没有主键,只有一个聚集索引,那么可以直接删除聚集索引,然后在重建聚集索引时指定分区架构,其实就是索引分区,只不过这个索引里存储的是真正的表的数据。

链接: http://blog.csdn.net/yupeigu/article/details/7754115

代码:



--1.创建数据库
create database wc
on primary
(
name = wc_data,
filename = 'D:\wc_data.mdf'
)
log on
(
name = wc_log1,
filename = 'd:\wc_log1.ldf'  
),
(
name = wc_log2,
filename = 'd:\wc_log2.ldf'
)


--2.增加文件组
alter database wc
add filegroup wc_fg1

alter database wc
add filegroup wc_fg2

alter database wc
add filegroup wc_fg3

alter database wc
add filegroup wc_fg4

--3.把文件添加到文件组中
alter database wc
add file
(
name = wc_fg1_1,
filename = 'd:\wc_fg1_1.ndf',


size = 1MB
)
to filegroup wc_fg1

alter database wc
add file
(
name = wc_fg2_1,
filename = 'd:\wc_fg2_1.ndf',
size = 1MB
)
to filegroup wc_fg2

alter database wc
add file
(
name = wc_fg3_1,
filename = 'd:\wc_fg3_1.ndf',
size = 1MB
)
to filegroup wc_fg3

alter database wc
add file
(
name = wc_fg4_1,
filename = 'd:\wc_fg4_1.ndf',
size = 1MB
)
to filegroup wc_fg4


--4.创建分区函数
use wc
go

create partition function wcLeftRange(datetime)
as range left for values('2006-01-01','2007-01-01','2008-01-01')

create partition function wcRightRange(datetime)
as range right for values('2006-01-01','2007-01-01','2008-01-01')


--5.创建分区方案
create partition scheme wcLeftRangeScheme
as partition wcLeftRange
to (wc_fg1,wc_fg2,wc_fg3,wc_fg4)



--下面的代码非常重要

--6.1创建表,下面是把已经存在的表改为分区表,其实分区表说到底就是对聚集索引的分区,
--所以只要重建主键索引就可以了
create table dbo.wcT
(wcId bigint not null,
 wcV varchar(100) not null ,
 wcDate datetime not null,
 
 constraint pk_wcid_date   --主键约束
 primary key(wcId,wcDate)  
)

--6.2添加数据
insert into dbo.wcT(wcId,wcV,wcDate)
values(1,'2','2006-01-01 00:00:00'),
      (2,'1','2005-12-31 23:59:59'),
      (3,'2','2006-12-31 23:59:59'),
      (4,'3','2007-01-01 00:00:00'),
      (5,'4','2008-01-01 00:00:00'),
      (6,'4','2008-12-31 23:59:59')


--6.3现在需要把原表按照一个分区架构来分区
--6.3.1如果这么删除,会报错,因为这个索引正用于 PRIMARY KEY 约束的强制执行
drop index pk_wcid_date on dbo.wcT


--6.5.2重建聚集索引,操作失败,因为表'wcT'上已存在名称为'pk_wcid_date'的索引或统计信息。
create clustered index pk_wcid_date on wcT(wcId,wcDate) 
on wcLeftRangeScheme(wcDate)


--6.3.3正确的方法:首先需要删除主键约束,应该这么写才是对的
alter table dbo.wcT
drop constraint pk_wcid_date


--6.3.4再次建立主键约束,指定创建聚集索引,同时指定分区架构
alter table dbo.wcT
add constraint pk_wcid_date primary key clustered (wcId,wcDate) 
on wcLeftRangeScheme(wcDate)




--7.显示每条数据所属分区号,从1开始计算


select *,

       --$partition函数,后面是分区函数名称,列名称
       $partition.wcLeftRange(wcDate) as partition 
from wcT

热点排行