カンパ〜イ!←最初の1杯目、なに頼む?

現在、VB.NETで読み込んだファイルのコードで
一件一件、データベースを検索してチェックを行っているのですが
とても処理時間がかかるので最初にデータベースの結果を
ワークテーブルか何かに溜めておいてそのワークテーブルに
検索をかけにいくことは可能でしょうか?
何か参考になるサイトなどありましたら教えてください。

.NETは2002です。

A 回答 (6件)

件数が多くなくて、メモリ容量も問題ないのであれば、


DataSetに溜めておくというのは、どうでしょうか?

DBにワークテーブルを作ってチェックの方が良い場合は、
.NET側ではなく、DB側にストアドを作って、
全レコードのチェック結果をまとめて返すというのが
良いと思います。
(そのやり方の方が良いのであれば、別で提示します)

簡単ではありますが、.NETのDataSetを使ったチェック処理を
VS.NET2002で、作ってみました。ご参考になれば幸いです

CSVデータの内容
1,A,111111
2,B,222222
3,C,333333
4,D,444444
5,E,555555

' ファイルを読む
' ファイルを読む
Dim fs As New System.IO.StreamReader("c:\aaa.csv", System.Text.Encoding.ASCII)
Dim buffer As String = fs.ReadToEnd()
fs.Close()

' レコード単位に分割
Dim crlf As Char() = {Chr(13)}
Dim records As String() = buffer.Split(crlf)
Dim record As String

' データテーブルを作る
Dim da As New System.Data.DataTable("aaa")
da.Columns.Add("column1", GetType(String))
da.Columns.Add("column2", GetType(String))
da.Columns.Add("column3", GetType(String))

' ファイルレコード → DataRow
For Each record In records

  If record.Trim().Equals("") Then
    Exit For
  End If

  Dim columns As String() = record.Split(","c)
  Dim i As Integer = 0
  Dim dr As DataRow = da.NewRow()
  For i = 0 To 2
    dr.Item(i) = columns.GetValue(i)
  Next
  da.Rows.Add(dr)

Next

' チェック処理
Dim searchKey As String = "111111"
Dim condition As String = String.Format("column3={0}", searchKey)
Dim hitRows As DataRow() = da.Select(condition)

If hitRows.Length > 0 Then
  ' レコードがある場合
  MessageBox.Show("レコードあり")

  ' TODO:この後は、レコードがある処理を行う
Else
  ' レコードがない場合
  MessageBox.Show("レコードなし")

  ' TODO:この後は、レコードがない処理を行う
End If
    • good
    • 0

データベース上のデータ件数と、


読み込むファイルの件数。
あと、データベース上のデータの更新頻度で、
最適解は変わってくると思います。

テキストファイルに比べて、データベース側の件数が圧倒的に多いのであればデータベースの取り込みを行うだけでも時間がかかるわけで。

下記にいくつか解決策が出てますが、そのあたりをふまえてどうするか考えるといいと思います。
(ちなみに私なら、全部DBに取り込んで、DB上でチェックします。主に慣れの問題が理由ですが)
    • good
    • 0

/abc__01__x/


Table_A01
Table_B02
/abc__01__y/
Table_A02
Table_B03

データベースをSQL Server や Oracle にしようともディスクアクセスの手続きを残せば高速化にも限界が。
データベースでデータで管理するのは当然だとしても、それを利用しなきゃならない決まりはないでしょう。

ファイルのコードで、ある程度、検索対象が決まるならなば、上述のようなテキストファイルを用意、
ファイルコードのマッチするテーブルデータだけを検索するという絞り込みをすれば高速化します。
もちろん、この場合、検索対象のテーブルはメモリ上に展開します。

経験では、1件90秒を要するような処理も0.001秒まで高速化できます。

私は、単なるデザイナでプログラマではありません。
ですから、<テーブルをメモリ上に展開>は、難しい手法を採用してはいません。
CないしVBでテーブルを巨大構造体に変換しバイナリファイルとして保存するだけです。
BLoad()、BSave() という関数を用意すること位、朝飯前でしょう。
そうすれば、瞬時にメモリ上に必要なテーブルを展開できます。
これで、ディスクアクセスの制約から解放されるという次第です。

どうしても高速化したいのであれば、メモリ上への検索データの展開も選択肢の一つかなと思います。
    • good
    • 0

多数のPC端末で同時にデータベースにアクセスする様な


場合には、データベースへの接続数に制限が有るので
普通に、初期起動時にデータベースから取得したデータを
メモリ上に確保した配列に保存した物を使用するので良い
と思いますが?

工夫する点が有るとすれば
1)検索用テーブルを作成する際にキー項目順でソートして
 おく。
  バイナリサーチを使った高速な検索が可能になるので
 テーブル全件を始めから順に検索せずにすみます。

2)項目が複数に分類分けできる時場合は、分類毎にテーブル
 を作成する。
  またテーブルの作成を起動時に行うのではなく、最初の
 検索が発生した時に行う様にすれば、テーブル作成の為に
 起動時間が遅くなるのを防ぐ事が可能になり、且つ無駄な
 メモリを使用せずにすみます。
    • good
    • 0

DB上にワークテーブルを作ってやる場合ですが、


SQL Server であれば、頭に「#」が付くテーブルをCREATE TABLEで
作成し、Bulk Insert で、一括登録させます。
(#付きテーブル名は、一定時間が過ぎると自動的にDROPされます)

■ワークテーブルの作成
http://www.techbank.jp/sqlserver/#a5

■Bulk Insert
http://www.techbank.jp/sqlserver/#a8

OracleでもSQL*LoaderなんかでUPする方法はあります。

後は、ワークテーブルの内容とチェックするマスタやテーブル等を
つき合わせてチェックするロジックを.NET側かストアド側で
書けばOKだと思いますが、如何でしょうか?
    • good
    • 0

すいません、下記は勘違いしました。



やり方としては、下記の応用で、比較対象データとなりうるデータを
一括して取得し、DataSetかDataTableに保存してあげます。
その後、DataTableのSelectメソッドを使い、検索条件(チェック条件)を
指定し、レコードの存在チェックや、その他のチェックができます。

Dim da As System.Data.DataTable = SQLやストアドのReaderでマスタ等のデータ取得

Dim hitRows As DataRow() = da.Select("検索キー = 検索値")
If hitRows.Length > 0 Then
  ' レコードが存在した場合のチェック処理
Else
  ' レコードがなかった場合の処理
End If

このやり方で、レスポンスがあがった事例はあるので、
お試し頂けたらと思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報