2017-09-17 3 views
0

数百万のレコードを挿入しようとしています。これを行うより速い方法がありますか? 1ファイルにつき30分かかるので、100以上のファイルがあります。私は特定のディレクトリ内のすべてのファイルを調べ、すべての行を調べ、すべてのファイルのすべての行をCassandraデータベースに挿入する必要があります。これらのファイルは、すべて1KB〜300,000 KBの範囲で最大サイズです。C#:Cassandraデータベースを使ってゆっくり挿入する

私が参照しているのは9734KBで、完了せずに30分間処理しています。確かにレコードを挿入するためのより速い方法が必要ですか?ファイルの処理には942,345行あります。

このレートでは、これらのレコードをすべて挿入するのに数日かかります。

はバッチとし、せずにそれを試してみましたが、両方とも同じ速さ(約)

Console.CursorVisible = false; 

var cluster = Cluster.Builder().AddContactPoints("127.0.0.1").Build(); 
var session = cluster.Connect("cracking"); 

Console.ForegroundColor = ConsoleColor.Green; 
Console.WriteLine(); 
Console.WriteLine(" [" + DateTime.Now.ToShortTimeString() + "]" + " Connected to the Cassandra Database"); 
Console.WriteLine(); 
Console.ForegroundColor = ConsoleColor.White; 

string filepath = @"C:\Users\admin\Desktop\wecrack lists\test"; 
DirectoryInfo directory = new DirectoryInfo(filepath); 

int fileCount = 0; 

foreach (var file in directory.GetFiles("*")) 
{ 
    fileCount++; 

    Console.WriteLine(" [" + DateTime.Now.ToShortTimeString() + "]" + " Working through file: {" + file + "} {" + fileCount + "/" + directory.GetFiles("*").Count() + "}"); 

    var lines = File.ReadLines(filepath + @"\" + file.ToString()).ToList(); 

    var batch = new BatchStatement(); 

    int lineCount = 0; 

    while (lines.Count > 0) 
    { 
     foreach (string line in lines.ToList()) 
     { 
      if (lineCount >= 2000) 
      { 
       lineCount = 0; 

       Console.WriteLine(" [" + DateTime.Now.ToShortTimeString() + "]" + " Changing batch for file: {" + file + "} {" + fileCount + "/" + directory.GetFiles("*").Count() + "}"); 
       session.Execute(batch); 
       batch = new BatchStatement(); 
       break; 
      } 

      lineCount++; 
      lines.Remove(line); 

      var userTrackStmt = session.Prepare("INSERT INTO passwords (id, password) VALUES (?, ?)"); 
      batch.Add(userTrackStmt.Bind(Guid.NewGuid(), line)); 
     } 
    } 
} 

Console.WriteLine(); 
Console.WriteLine(" [" + DateTime.Now.ToShortTimeString() + "]" + " Finished inserting records, press any key to get the count."); 
Console.ReadKey(true); 

Console.WriteLine(); 
Console.ForegroundColor = ConsoleColor.Cyan; 
Console.WriteLine(" " + string.Format("{0:n0}", session.Execute("SELECT * FROM passwords").Count()) + " records."); 

while (true) 
{ 
    Console.ReadKey(true); 
} 
+0

あなたのコードで懸念事項をいくつか分けて、ここに結果を投稿できますか?つまり、DBからI/O操作を分離してください。 – user2347763

+0

cassandraへの接続と書き込みに使用しているライブラリはどれですか? –

+0

バッチ処理を行う必要はありません。バッチ処理では、必要のないトランザクション保証が得られます。準備されたステートメントですべてのインサートを個別に送信するだけです。 – Slugart

答えて

1

あなたは声明にあなたがそれを使用するたびに用意する必要はありません。これを一度準備し、挿入操作ごとにバインドする必要があります。

また、user23477763で提案されている懸念事項を除外する必要があります。多数のリストを作成し、それらのリストの最初から削除するコストを分けることができます。

バッチ処理を行う必要はありません。バッチ処理では、必要のないトランザクションの保証が得られます。スキーマがどのように見えるかを知らなくても、正確な影響が何であるかを知ることは難しいです。一読するhttps://docs.datastax.com/en/cql/3.3/cql/cql_using/useBatchBadExample.html

また、複数の挿入操作を同時に行うこともできます。

関連する問題