検索
ホームページバックエンド開発PHPチュートリアルSqlserver の挿入速度の遅さや大量のデータのデータ損失に対する解決策

私のデバイスは毎秒 2,000 個のデータをデータベースに挿入し、2 台のデバイスで合計 4,000 個のデータをプログラムの挿入ステートメントを使用して挿入する場合、同時に挿入する 2 台のデバイスで合計約 2,800 個のデータを挿入できます。 1,200 件のデータが失われています。約 100 件の記事で、多くの方法をテストし、明らかな効果が得られる 2 つの解決策を整理しました。

方法 1: 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,&#39;&#39;+@Data+&#39;&#39;,@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,&#39;&#39;+@Data+&#39;&#39;,@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,&#39;&#39;+@Data+&#39;&#39;,@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,&#39;&#39;+@Data+&#39;&#39;,@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,&#39;&#39;+@Data+&#39;&#39;,@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,&#39;&#39;+@Data+&#39;&#39;,@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](&#39;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&#39;,&#39;;&#39;,&#39;|&#39;);

5. 結果の表示:

select * from [mytable] ;

大量のデータを挿入する最初の操作は、ファイルデータをデータベースに一括挿入

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
&#39;code001&#39;, &#39;name001&#39;, &#39;memo001&#39;, &#39;备注&#39; union all select
&#39;code002&#39;, &#39;name002&#39;, &#39;memo002&#39;, &#39;备注&#39; union all select
&#39;code003&#39;, &#39;name003&#39;, &#39;memo003&#39;, &#39;备注&#39; union all select
&#39;code004&#39;, &#39;name004&#39;, &#39;memo004&#39;, &#39;备注&#39; union all select
&#39;code005&#39;, &#39;name005&#39;, &#39;memo005&#39;, &#39;备注&#39; union all select
&#39;code006&#39;, &#39;name006&#39;, &#39;memo006&#39;, &#39;备注&#39;

xp_cmdshellストアドプロシージャを有効にする(開いた後にセキュリティリスクがあります)

EXEC sp_configure &#39;show advanced options&#39;, 1;
RECONFIGURE;EXEC sp_configure &#39;xp_cmdshell&#39;, 1;
EXEC sp_configure &#39;show advanced options&#39;, 0;
RECONFIGURE;

bcp を使用してフォーマット ファイルをエクスポートする:

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

bcp を使用してデータ ファイルをエクスポートする:

EXEC master..xp_cmdshell &#39;BCP db_mgr.dbo.T_Student out C:/student.data -f C:/student_fmt.xml -T&#39;

テーブル内のデータをクリアする

truncate table db_mgr.dbo.T_Student

Bulk Insert ステートメントを使用してデータ ファイルをバッチ インポートする:

BULK INSERT db_mgr.dbo.T_Student
FROM &#39;C:/student.data&#39;
WITH
(
  FORMATFILE = &#39;C:/student_fmt.xml&#39;
)
OpenRowset(Bulk)を使用:

t_studentテーブルはすでに存在する必要がありますopenrowset(bulk)の使用のredrreeeeexample:sqlserverの遅い挿入速度に対する存在する必要はありません。大量のデータまたはデータ損失の解決策に関連する記事については、PHP 中国語 Web サイトに注目してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
PHPのPDOとは何ですか?PHPのPDOとは何ですか?Apr 28, 2025 pm 04:51 PM

この記事では、PHPのデータベースアクセスの拡張機能であるPHPデータオブジェクト(PDO)について説明します。これは、データベースの抽象化やより良いエラー処理など、準備されたステートメントとMySQLIに対する利点を通じてセキュリティを強化する上でのPDOの役割を強調しています。

MemcacheとPHPでMemcachedとは何ですか? PHPのいくつかのプロジェクト間でMemcacheの単一のインスタンスを共有することは可能ですか?MemcacheとPHPでMemcachedとは何ですか? PHPのいくつかのプロジェクト間でMemcacheの単一のインスタンスを共有することは可能ですか?Apr 28, 2025 pm 04:47 PM

MemcacheとMemcachedは、データベースの負荷を減らすことでWebアプリをスピードアップするPHPキャッシュシステムです。単一のインスタンスは、慎重な主要な管理を使用してプロジェクト間で共有できます。

MySQLとPHPを使用して新しいデータベースを作成するための手順は何ですか?MySQLとPHPを使用して新しいデータベースを作成するための手順は何ですか?Apr 28, 2025 pm 04:44 PM

記事では、PHPを使用してMySQLデータベースを作成および管理する手順について説明し、接続、作成、共通エラー、セキュリティ対策に焦点を当てています。

JavaScriptはPHPと相互作用しますか?JavaScriptはPHPと相互作用しますか?Apr 28, 2025 pm 04:43 PM

この記事では、JavaScriptとPHPが異なる環境のためにHTTP要求を通じて間接的にどのように相互作用するかについて説明します。 JavaScriptからPHPにデータを送信する方法をカバーし、データ検証やPROTなどのセキュリティ上の考慮事項を強調しています

コマンドラインからPHPスクリプトを実行する方法は?コマンドラインからPHPスクリプトを実行する方法は?Apr 28, 2025 pm 04:41 PM

この記事では、手順、一般的なオプション、トラブルシューティングエラー、セキュリティ上の考慮事項など、コマンドラインからPHPスクリプトの実行について説明します。

PHPの洋ナシとは何ですか?PHPの洋ナシとは何ですか?Apr 28, 2025 pm 04:38 PM

Pearは、再利用可能なコンポーネントのPHPフレームワークであり、パッケージ管理、コーディング基準、およびコミュニティサポートによる開発を強化しています。

PHPの用途は何ですか?PHPの用途は何ですか?Apr 28, 2025 pm 04:37 PM

PHPは、主にWeb開発に使用される多用途のスクリプト言語であり、動的ページを作成し、コマンドラインスクリプト、デスクトップアプリ、API開発にも使用できます。

PHPの古い名前は何でしたか?PHPの古い名前は何でしたか?Apr 28, 2025 pm 04:36 PM

この記事では、1995年の「パーソナルホームページツール」から1998年の「PHP:HyperText Preprocessor」へのPHPの進化について説明し、個人のWebサイトを超えた使用の拡大を反映しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール