一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫(kù)技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫(kù) - Sql Server - 針對(duì)Sqlserver大數(shù)據(jù)量插入速度慢或丟失數(shù)據(jù)的解決方法

針對(duì)Sqlserver大數(shù)據(jù)量插入速度慢或丟失數(shù)據(jù)的解決方法

2020-03-25 15:08shichen2014 Sql Server

這篇文章主要介紹了針對(duì)Sqlserver大數(shù)據(jù)量插入速度慢或丟失數(shù)據(jù)的解決方法,很有實(shí)用價(jià)值,需要的朋友可以參考下

我的設(shè)備上每秒將2000條數(shù)據(jù)插入數(shù)據(jù)庫(kù),2個(gè)設(shè)備總共4000條,當(dāng)在程序里面直接用insert語(yǔ)句插入時(shí),兩個(gè)設(shè)備同時(shí)插入大概總共能插入約2800條左右,數(shù)據(jù)丟失約1200條左右,測(cè)試了很多方法,整理出了兩種效果比較明顯的解決辦法:

方法一:使用Sql Server函數(shù):

1.將數(shù)據(jù)組合成字串,使用函數(shù)將數(shù)據(jù)插入內(nèi)存表,后將內(nèi)存表數(shù)據(jù)復(fù)制到要插入的表。

2.組合成的字符換格式:'111|222|333|456,7894,7458|0|1|2014-01-01 12:15:16;1111|2222|3333|456,7894,7458|0|1|2014-01-01 12:15:16',每行數(shù)據(jù)中間用“;”隔開,每個(gè)字段之間用“|”隔開。

3.編寫函數(shù):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
CREATE FUNCTION [dbo].[fun_funcname](@str VARCHAR(max),@splitchar CHAR(1),@splitchar2 CHAR(1))
--定義返回表 
RETURNS @t TABLE(MaxValue float,Phase int,SlopeValue float,Data varchar(600),Alarm int,AlmLev int,GpsTime datetime,UpdateTime datetime) AS  
/*    
author:hejun li  
create date:2014-06-09  
*/  
BEGIN  
DECLARE @substr VARCHAR(max),@substr2 VARCHAR(max)
--申明單個(gè)接收值
declare @MaxValue float,@Phase int,@SlopeValue float,@Data varchar(8000),@Alarm int,@AlmLev int,@GpsTime datetime
SET @substr=@str  
DECLARE @i INT,@j INT,@ii INT,@jj INT,@ijj1 int,@ijj2 int,@m int,@mm int
SET @j=LEN(REPLACE(@str,@splitchar,REPLICATE(@splitchar,2)))-LEN(@str)--獲取分割符個(gè)數(shù)  
IF @j=0  
  BEGIN  
   --INSERT INTO @t VALUES (@substr,1) --沒有分割符則插入整個(gè)字串 
   set @substr2=@substr;
   set @ii=0
   SET @jj=LEN(REPLACE(@substr2,@splitchar2,REPLICATE(@splitchar2,2)))-LEN(@substr2)--獲取分割符個(gè)數(shù)
     WHILE @ii<=@jj
        BEGIN
          if(@ii<@jj)
            begin
              SET @mm=CHARINDEX(@splitchar2,@substr2)-1 --獲取分割符的前一位置
              if(@ii=0)
                set @MaxValue=cast(LEFT(@substr2,@mm) as float)
              else if(@ii=1)
                set @Phase=cast(LEFT(@substr2,@mm) as int)
              else if(@ii=2)
                set @SlopeValue=cast(LEFT(@substr2,@mm) as float)
              else if(@ii=3)
                set @Data=cast(LEFT(@substr2,@mm) as varchar)
              else if(@ii=4)
                set @Alarm=cast(LEFT(@substr2,@mm) as int)
              else if(@ii=5)
                set @AlmLev=cast(LEFT(@substr2,@mm) as int)
              else if(@ii=6)
                INSERT INTO @t VALUES(@MaxValue,@Phase,@SlopeValue,''+@Data+'',@Alarm,@AlmLev,cast(@substr2 as datetime),GETDATE())
              SET @substr2=RIGHT(@substr2,LEN(@substr2)-(@mm+1)) --去除已獲取的分割串,得到還需要繼續(xù)分割的字符串
            end
          else
            BEGIN
              --當(dāng)循環(huán)到最后一個(gè)值時(shí)將數(shù)據(jù)插入表
              INSERT INTO @t VALUES(@MaxValue,@Phase,@SlopeValue,''+@Data+'',@Alarm,@AlmLev,cast(@substr2 as datetime),GETDATE())
            END
        --END
        SET @ii=@ii+1
      END
  END  
ELSE  
BEGIN  
 SET @i=0  
 WHILE @i<=@j  
 BEGIN  
  IF(@i<@j)  
  BEGIN  
  SET @m=CHARINDEX(@splitchar,@substr)-1 --獲取分割符的前一位置
  --INSERT INTO @t VALUES(LEFT(@substr,@m),@i+1)
  -----二次循環(huán)開始
  --1.線獲取要二次截取的字串
  set @substr2=(LEFT(@substr,@m));
  --2.初始化二次截取的起始位置
  set @ii=0
  --3.獲取分隔符個(gè)數(shù)
  SET @jj=LEN(REPLACE(@substr2,@splitchar2,REPLICATE(@splitchar2,2)))-LEN(@substr2)--獲取分割符個(gè)數(shù)
  WHILE @ii<=@jj
    BEGIN
      if(@ii<@jj)
        begin
          SET @mm=CHARINDEX(@splitchar2,@substr2)-1 --獲取分割符的前一位置
          if(@ii=0)
            set @MaxValue=cast(LEFT(@substr2,@mm) as float)
          else if(@ii=1)
            set @Phase=cast(LEFT(@substr2,@mm) as int)
          else if(@ii=2)
            set @SlopeValue=cast(LEFT(@substr2,@mm) as float)
          else if(@ii=3)
            set @Data=cast(LEFT(@substr2,@mm) as varchar)
          else if(@ii=4)
            set @Alarm=cast(LEFT(@substr2,@mm) as int)
          else if(@ii=5)
            set @AlmLev=cast(LEFT(@substr2,@mm) as int)
          else if(@ii=6)
            INSERT INTO @t VALUES(@MaxValue,@Phase,@SlopeValue,''+@Data+'',@Alarm,@AlmLev,cast(@substr2 as datetime),GETDATE())
          SET @substr2=RIGHT(@substr2,LEN(@substr2)-(@mm+1)) --去除已獲取的分割串,得到還需要繼續(xù)分割的字符串
        end
      else
        BEGIN
          --當(dāng)循環(huán)到最后一個(gè)值時(shí)將數(shù)據(jù)插入表
          INSERT INTO @t VALUES(@MaxValue,@Phase,@SlopeValue,''+@Data+'',@Alarm,@AlmLev,cast(@substr2 as datetime),GETDATE())
        END
    --END
    SET @ii=@ii+1
  END
  -----二次循環(huán)結(jié)束
  SET @substr=RIGHT(@substr,LEN(@substr)-(@m+1)) --去除已獲取的分割串,得到還需要繼續(xù)分割的字符串  
  END  
 ELSE  
  BEGIN
  --INSERT INTO @t VALUES(@substr,@i+1)--對(duì)最后一個(gè)被分割的串進(jìn)行單獨(dú)處理
  -----二次循環(huán)開始
  --1.線獲取要二次截取的字串
  set @substr2=@substr;
  --2.初始化二次截取的起始位置
  set @ii=0
  --3.獲取分隔符個(gè)數(shù)
  SET @jj=LEN(REPLACE(@substr2,@splitchar2,REPLICATE(@splitchar2,2)))-LEN(@substr2)--獲取分割符個(gè)數(shù)
  WHILE @ii<=@jj
    BEGIN
      if(@ii<@jj)
        begin
          SET @mm=CHARINDEX(@splitchar2,@substr2)-1 --獲取分割符的前一位置
          if(@ii=0)
            set @MaxValue=cast(LEFT(@substr2,@mm) as float)
          else if(@ii=1)
            set @Phase=cast(LEFT(@substr2,@mm) as int)
          else if(@ii=2)
            set @SlopeValue=cast(LEFT(@substr2,@mm) as float)
          else if(@ii=3)
            set @Data=cast(LEFT(@substr2,@mm) as varchar)
          else if(@ii=4)
            set @Alarm=cast(LEFT(@substr2,@mm) as int)
          else if(@ii=5)
            set @AlmLev=cast(LEFT(@substr2,@mm) as int)
          else if(@ii=6)
            INSERT INTO @t VALUES(@MaxValue,@Phase,@SlopeValue,''+@Data+'',@Alarm,@AlmLev,cast(@substr2 as datetime),GETDATE())
          SET @substr2=RIGHT(@substr2,LEN(@substr2)-(@mm+1)) --去除已獲取的分割串,得到還需要繼續(xù)分割的字符串
        end
      else
        BEGIN
          --當(dāng)循環(huán)到最后一個(gè)值時(shí)將數(shù)據(jù)插入表
          INSERT INTO @t VALUES(@MaxValue,@Phase,@SlopeValue,''+@Data+'',@Alarm,@AlmLev,cast(@substr2 as datetime),GETDATE())
        END
    SET @ii=@ii+1
  END
  -----二次循環(huán)結(jié)束
  END  
 SET @i=@i+1   
 END  
END  
RETURN  
END

4.調(diào)用函數(shù)語(yǔ)句:

?
1
insert into [mytable] select * from [dbo].[fun_funcname]('111|222|333|456,7894,7458|0|1|2014-01-01 12:15:16;1111|2222|3333|456,7894,7458|0|1|2014-01-01 12:15:16',';','|');

5.結(jié)果展示:

?
1
select * from [mytable] ;

方法二:使用BULK INSERT

大數(shù)據(jù)量插入第一種操作,使用Bulk將文件數(shù)據(jù)插入數(shù)據(jù)庫(kù)

Sql代碼

創(chuàng)建數(shù)據(jù)庫(kù)

?
1
2
CREATE DATABASE [db_mgr]
GO

創(chuàng)建測(cè)試表

?
1
2
3
4
5
6
7
8
9
10
USE db_mgr
CREATE TABLE dbo.T_Student(
  F_ID [int] IDENTITY(1,1) NOT NULL,
  F_Code varchar(10) ,
  F_Name varchar(100) ,
  F_Memo nvarchar(500) ,
  F_Memo2 ntext ,
  PRIMARY KEY (F_ID)
)
GO

填充測(cè)試數(shù)據(jù)

?
1
2
3
4
5
6
7
Insert Into T_Student(F_Code, F_Name, F_Memo, F_Memo2) select
'code001', 'name001', 'memo001', '備注' union all select
'code002', 'name002', 'memo002', '備注' union all select
'code003', 'name003', 'memo003', '備注' union all select
'code004', 'name004', 'memo004', '備注' union all select
'code005', 'name005', 'memo005', '備注' union all select
'code006', 'name006', 'memo006', '備注'

開啟xp_cmdshell存儲(chǔ)過程(開啟后有安全隱患)

?
1
2
3
4
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;
EXEC sp_configure 'show advanced options', 0;
RECONFIGURE;

使用bcp導(dǎo)出格式文件:

?
1
EXEC master..xp_cmdshell 'BCP db_mgr.dbo.T_Student format nul -f C:/student_fmt.xml -x -c -T'

使用bcp導(dǎo)出數(shù)據(jù)文件:

?
1
EXEC master..xp_cmdshell 'BCP db_mgr.dbo.T_Student out C:/student.data -f C:/student_fmt.xml -T'

將表中數(shù)據(jù)清空

?
1
truncate table db_mgr.dbo.T_Student

使用Bulk Insert語(yǔ)句批量導(dǎo)入數(shù)據(jù)文件:

?
1
2
3
4
5
6
BULK INSERT db_mgr.dbo.T_Student
FROM 'C:/student.data'
WITH
(
  FORMATFILE = 'C:/student_fmt.xml'
)

使用OPENROWSET(BULK)的例子:

T_Student表必須已存在

?
1
2
INSERT INTO db_mgr.dbo.T_Student(F_Code, F_Name) SELECT F_Code, F_Name
FROM OPENROWSET(BULK N'C:/student.data', FORMATFILE=N'C:/student_fmt.xml') AS new_table_name

使用OPENROWSET(BULK)的例子:

tt表可以不存在

?
1
2
SELECT F_Code, F_Name INTO db_mgr.dbo.tt
FROM OPENROWSET(BULK N'C:/student.data', FORMATFILE=N'C:/student_fmt.xml') AS new_table_name

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 视频在线视频免费观看 | 午夜 在线播放 | 国产精品午夜国产小视频 | 闺蜜的样子小说安沁在线阅读 | 黄版快手| 欧美日韩国产成人综合在线 | 日韩伦理在线免费观看 | 天天爱天天操天天射 | 久久嫩草影院网站 | 午夜剧场1000| 国产精品高清视亚洲一区二区 | 天天操天天射天天爽 | 男人肌肌捅女人肌肌 | 成人观看免费大片在线观看 | 国产精品99久久久 | 国内精品久久久久影院嫩草 | 国产盗摄美女嘘嘘视频 | 挺进白嫩老师下面视频 | 手机国产乱子伦精品视频 | 精品国产综合区久久久久久 | 亚洲欧美一区二区三区在线观看 | 国产欧美日韩不卡 | 国产成人精品高清在线 | 亚洲高清在线视频 | 国产第一综合另类色区奇米 | 国产精品毛片高清在线完整版 | 国产91精品区| 网站视频免费 | 国产美女亚洲精品久久久综合91 | 91这里只有精品 | 欧美三级不卡在线观线看高清 | 成人久久18免费网站 | 手机在线免费观看视频 | 涩涩屋在线观看 | 为什么丈夫插我我却喜欢被打着插 | 国产高清专区 | 青青草亚洲 | 亚洲成人三级 | 久久国产伦子伦精品 | 青青草国产精品久久碰 | 日本一区二区高清免费不卡 |