婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 針對Sqlserver大數據量插入速度慢或丟失數據的解決方法

針對Sqlserver大數據量插入速度慢或丟失數據的解決方法

熱門標簽:地圖標注一個圓圈怎么用 如何在地圖標注自己店鋪 400外呼系統合法 洛陽外呼系統平臺 真人語音電銷機器人 廣州人工電銷機器人費用 電銷機器人被曝光 寧波人工外呼系統有效果嗎 怎樣把地圖標注導入公司地址

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

方法一:使用Sql Server函數:

1.將數據組合成字串,使用函數將數據插入內存表,后將內存表數據復制到要插入的表。

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',每行數據中間用“;”隔開,每個字段之間用“|”隔開。

3.編寫函數:

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)
--申明單個接收值 
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)--獲取分割符個數   
IF @j=0   
  BEGIN   
   --INSERT INTO @t VALUES (@substr,1) --沒有分割符則插入整個字串  
   set @substr2=@substr;
   set @ii=0
   SET @jj=LEN(REPLACE(@substr2,@splitchar2,REPLICATE(@splitchar2,2)))-LEN(@substr2)--獲取分割符個數
     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)) --去除已獲取的分割串,得到還需要繼續分割的字符串
            end
          else
            BEGIN
              --當循環到最后一個值時將數據插入表
              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) 
  -----二次循環開始
  --1.線獲取要二次截取的字串
  set @substr2=(LEFT(@substr,@m));
  --2.初始化二次截取的起始位置
  set @ii=0
  --3.獲取分隔符個數
  SET @jj=LEN(REPLACE(@substr2,@splitchar2,REPLICATE(@splitchar2,2)))-LEN(@substr2)--獲取分割符個數
  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)) --去除已獲取的分割串,得到還需要繼續分割的字符串
        end
      else
        BEGIN
          --當循環到最后一個值時將數據插入表
          INSERT INTO @t VALUES(@MaxValue,@Phase,@SlopeValue,''+@Data+'',@Alarm,@AlmLev,cast(@substr2 as datetime),GETDATE())
        END
    --END
    SET @ii=@ii+1
  END
  -----二次循環結束
  SET @substr=RIGHT(@substr,LEN(@substr)-(@m+1)) --去除已獲取的分割串,得到還需要繼續分割的字符串   
  END   
 ELSE   
  BEGIN
  --INSERT INTO @t VALUES(@substr,@i+1)--對最后一個被分割的串進行單獨處理 
  -----二次循環開始
  --1.線獲取要二次截取的字串
  set @substr2=@substr;
  --2.初始化二次截取的起始位置
  set @ii=0
  --3.獲取分隔符個數
  SET @jj=LEN(REPLACE(@substr2,@splitchar2,REPLICATE(@splitchar2,2)))-LEN(@substr2)--獲取分割符個數
  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)) --去除已獲取的分割串,得到還需要繼續分割的字符串
        end
      else
        BEGIN
          --當循環到最后一個值時將數據插入表
          INSERT INTO @t VALUES(@MaxValue,@Phase,@SlopeValue,''+@Data+'',@Alarm,@AlmLev,cast(@substr2 as datetime),GETDATE())
        END
    SET @ii=@ii+1
  END
  -----二次循環結束
  END   
 SET @i=@i+1    
 END   
END   
RETURN   
END 

4.調用函數語句:

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.結果展示:

select * from [mytable] ;

方法二:使用BULK INSERT

大數據量插入第一種操作,使用Bulk將文件數據插入數據庫

Sql代碼

創建數據庫

CREATE DATABASE [db_mgr] 
GO 

創建測試表

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

填充測試數據

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存儲過程(開啟后有安全隱患)

EXEC sp_configure 'show advanced options', 1; 
RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1; 
EXEC sp_configure 'show advanced options', 0; 
RECONFIGURE;

使用bcp導出格式文件:

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

使用bcp導出數據文件:

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

將表中數據清空

truncate table db_mgr.dbo.T_Student

使用Bulk Insert語句批量導入數據文件:

BULK INSERT db_mgr.dbo.T_Student 
FROM 'C:/student.data'
WITH
( 
  FORMATFILE = 'C:/student_fmt.xml'
)

使用OPENROWSET(BULK)的例子:

T_Student表必須已存在

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表可以不存在

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

您可能感興趣的文章:
  • c#幾種數據庫的大數據批量插入(SqlServer、Oracle、SQLite和MySql)
  • Sqlserver 高并發和大數據存儲方案

標簽:南昌 煙臺 晉中 北海 東營 咸寧 珠海 石家莊

巨人網絡通訊聲明:本文標題《針對Sqlserver大數據量插入速度慢或丟失數據的解決方法》,本文關鍵詞  針對,Sqlserver,大,數據,量,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《針對Sqlserver大數據量插入速度慢或丟失數據的解決方法》相關的同類信息!
  • 本頁收集關于針對Sqlserver大數據量插入速度慢或丟失數據的解決方法的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 花垣县| 固阳县| 紫阳县| 林甸县| 旌德县| 尼木县| 康定县| 陈巴尔虎旗| 曲靖市| 牙克石市| 泰兴市| 西安市| 海安县| 冀州市| 大冶市| 靖江市| 洪雅县| 定南县| 恭城| 凤凰县| 吉首市| 东明县| 郴州市| 灵寿县| 陇川县| 白玉县| 东海县| 浏阳市| 瑞昌市| 寿宁县| 安宁市| 肇东市| 宁波市| 锦州市| 京山县| 建水县| 贵德县| 乌拉特中旗| 申扎县| 大港区| 广元市|