一个视图查出来15亿数据。(视图包含有10个视图,一个视图有100个表。一个表有150万行数据,)
跟据字段中的QQ号。分别插入150个表中。我写了一个存储过程。一个小时才30万数据。
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GOCREATE PROCEDURE get_mycursor
AS --定义游标mycursor
DECLARE mycursor CURSOR FOR --使用游标的对象(QQ表)
SELECT QQNum,Nick,Age,Gender,Auth,QunNum FROM group1_100 --打开游标
OPEN mycursor DECLARE
@QQNum VARCHAR(50),
@Nick VARCHAR(50),
@Age VARCHAR(50),
@Gender VARCHAR(50),
@Auth VARCHAR(50),
@QunNum VARCHAR(50),
@sql VARCHAR(500) --将游标向下移1行,获取的数据放入之前定义的变量@QQNum,@Nick,@Age,@Gender,@Auth,@QunNum 中
FETCH NEXT FROM mycursor INTO @QQNum,@Nick,@Age,@Gender,@Auth,@QunNum --判断是否成功获取数据
WHILE @@fetch_status=0
BEGIN
SET @sql=''--判断QQ是不是七位数的还是八位的
IF(LEN(@QQNum)>7)
BEGIN
--如果是八位数以上的。跟据条件动态拼成插入某表的sql语句
SET @sql=' INSERT newlist'+SUBSTRING(@QQNum,1,LEN(@QQNum)-7)+' (QQNum,Nick,Age,Gender,Auth,QunNum)
VALUES( '+''''+@QQNum+''''+','+''''+@Nick+''''+','+''''+@Age+''''+','+''''+@Gender+''''+','+''''+@Auth+''''+','+''''+@QunNum+''''+')'
END
ELSE
BEGIN
--低于七位数,直接拼成插入newlist0这个表
SET @sql=' INSERT newlist0 (QQNum,Nick,Age,Gender,Auth,QunNum)
VALUES( '+''''+@QQNum+''''+','+''''+@Nick+''''+','+''''+@Age+''''+','+''''+@Gender+''''+','+''''+@Auth+''''+','+''''+@QunNum+''''+')'
END
--运行运态语句
EXEC(@sql); FETCH NEXT FROM mycursor INTO @QQNum,@Nick,@Age,@Gender,@Auth,@QunNum --将游标向下移1行
END
--关闭游标
CLOSE mycursor --删除游标
DEALLOCATE mycursor
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
跟据字段中的QQ号。分别插入150个表中。我写了一个存储过程。一个小时才30万数据。
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GOCREATE PROCEDURE get_mycursor
AS --定义游标mycursor
DECLARE mycursor CURSOR FOR --使用游标的对象(QQ表)
SELECT QQNum,Nick,Age,Gender,Auth,QunNum FROM group1_100 --打开游标
OPEN mycursor DECLARE
@QQNum VARCHAR(50),
@Nick VARCHAR(50),
@Age VARCHAR(50),
@Gender VARCHAR(50),
@Auth VARCHAR(50),
@QunNum VARCHAR(50),
@sql VARCHAR(500) --将游标向下移1行,获取的数据放入之前定义的变量@QQNum,@Nick,@Age,@Gender,@Auth,@QunNum 中
FETCH NEXT FROM mycursor INTO @QQNum,@Nick,@Age,@Gender,@Auth,@QunNum --判断是否成功获取数据
WHILE @@fetch_status=0
BEGIN
SET @sql=''--判断QQ是不是七位数的还是八位的
IF(LEN(@QQNum)>7)
BEGIN
--如果是八位数以上的。跟据条件动态拼成插入某表的sql语句
SET @sql=' INSERT newlist'+SUBSTRING(@QQNum,1,LEN(@QQNum)-7)+' (QQNum,Nick,Age,Gender,Auth,QunNum)
VALUES( '+''''+@QQNum+''''+','+''''+@Nick+''''+','+''''+@Age+''''+','+''''+@Gender+''''+','+''''+@Auth+''''+','+''''+@QunNum+''''+')'
END
ELSE
BEGIN
--低于七位数,直接拼成插入newlist0这个表
SET @sql=' INSERT newlist0 (QQNum,Nick,Age,Gender,Auth,QunNum)
VALUES( '+''''+@QQNum+''''+','+''''+@Nick+''''+','+''''+@Age+''''+','+''''+@Gender+''''+','+''''+@Auth+''''+','+''''+@QunNum+''''+')'
END
--运行运态语句
EXEC(@sql); FETCH NEXT FROM mycursor INTO @QQNum,@Nick,@Age,@Gender,@Auth,@QunNum --将游标向下移1行
END
--关闭游标
CLOSE mycursor --删除游标
DEALLOCATE mycursor
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
然后,在插入时禁用表中所有索引和不必要的触发器,等插入完再启用。同时插入时数据库的恢复模式改成大容量日志(可以在插入时才改)。
第三,千万不要用游标,你的游标不把数据库弄死已经非常了得了。
第四,看看可以不可以使用到BULK INSERT这类动作,这类操作是目前为止插入速度最快的操作。基本上没有更快的了(除非科研级别的数据库)
不能用游标,循环一次游标相当于执行一条sql语句的效率,会进行很多表扫描
直接用语句
INSERT newlist(a,b,d,e) select a,b,c,d from group1_100 where LEN(QQNum)>7
INSERT newlist0(a,b,d,e) select a,b,c,d from group1_100 where LEN(QQNum)<=7
1、不使用游标;
2、大数据量批量导出时,防止数据库做完整性检查以及索引和日志的创建,因为本身是导出操作,不担心数据的丢失和数据的正确性,日志和完整性已没有必要。
所以先去掉索引和其他的约束,另外,不清楚sql server里面的是否有停用日志记录的,呵呵。
然后,就是等数据导出完成后,再把索引这些加上。
补充一句,上面那个停用日志是对整个数据库起作用,慎用慎用。
CREATE PROCEDURE get_mycursor
AS --低于七位数,直接拼成插入newlist0这个表
INSERT Into newlist0
Select QQNum,Nick,Age,Gender,Auth,QunNum FROM group1_100 Where LEN(QQNum)<=7 --定义游标mycursor
DECLARE mycursor CURSOR FOR --使用游标的对象(QQ表)
SELECT Distinct SUBSTRING(QQNum,1,LEN(QQNum)-7) QQNum FROM group1_100 Where LEN(QQNum)> 7 --打开游标
OPEN mycursor DECLARE
@QQNum VARCHAR(50)
@sql VARCHAR(500) --将游标向下移1行,获取的数据放入之前定义的变量@QQNum,@Nick,@Age,@Gender,@Auth,@QunNum 中
FETCH NEXT FROM mycursor INTO @QQNum --判断是否成功获取数据
WHILE @@fetch_status==0
BEGIN
SET @sql='' --如果是八位数以上的。跟据条件动态拼成插入某表的sql语句
SET @sql=' INSERT newlist'+@QQNum+' (QQNum,Nick,Age,Gender,Auth,QunNum)
Select QQNum,Nick,Age,Gender,Auth,QunNum FROM group1_100 Where SUBSTRING(QQNum,1,LEN(QQNum)-7)= '''+@QQNum+'''' --运行运态语句
EXEC(@sql); FETCH NEXT FROM mycursor INTO @QQNum --将游标向下移1行
END
--关闭游标
CLOSE mycursor --删除游标
DEALLOCATE mycursor GO