DOBON.NET DOBON.NETプログラミング掲示板過去ログ

テキストからテーブルへのデータ取込みについて

環境/言語:[win2000 vb6]
分類:[VB6以前]

お世話になります こう ともうします。

現在WIN2000 vb6 oracle にて開発を行っています。

現在行っている処理はテキストのデータ(固定長)を読み込み
ワークテーブルへインサートする処理を行い、その後そのワーク
テーブルから全件をSELECTしそのデータを本番テーブルへINSERT
するプログラムを作成しています。
(ワークテーブルと本番テーブルのレイアウトは同じ)

今20万件のデータを取り込む際に
@ファイルデータ → ワークテーブル 約20分
Aワークテーブル → 本番テーブル 約6分30秒

と約3倍の差があります。
この@の方の処理時間を改善したのですが、いろいろ試したのですが
時間的にはほとんどかわりませんでした。

************* @のプログラム手順 *************

Line Input #1, BUF_LOCAL データを1行取得
次に
StrConv(MidB(StrConv(BUF_LOCAL, vbFromUnicode), from, to), vbUnicode)
にて取得したでーたをバイト区切りにて取得し
構造体の配列にセットしています。
その後構造体の配列をループさせINSERT作業をおこなっています。

************* やってみたこと。 *************
インターネットのサイト等でLine Inputは遅いので
FileSystemObject と TextStream を使いテキストデータを
読み込んでINSERT処理を行ったのですが、ほとんどスピードは
変わりませんでした。

何かわかる方がおられましたら宜しくお願いします。

以上
■No20913に返信(こうさんの記事)
似たような事をした事があります。
テキストファイルで、辞書情報の単語を数十万件〜数百万件DBに登録をしていた時の方法です。
言語も違い、実現できない事があるはずですが、参考になればどうぞ。

テキストファイルを全件FileStreamでメモリ上に展開して、
各行単位に配列に格納します。

格納後、複数の支社から同一単語が含まれてきている可能性があるので、
配列にはいっている文字列をソートします。(重複登録をなくす為)

ソート完了後に、直前の単語が同一かをチェック後にスレッドの処理に
引き渡します。

スレッド側での処理で、単語がそのままキーになっていたので、
重複分は除かれている前提で、DBにアクセスを行い、
Insert処理を各単語単位で別々に流します。

ここから先は私の理解の範疇を超えます・・・お勉強中です。
実際のこのクラス作成者は、別人でした。

スレッドのMax数を管理する為に、各スレッドは、スレッド待機数管理クラスが
実行されているスレッド数を見ながらスレッドを実行する為、
一旦ここに格納されていました。

言語はC#でした。

時間は、やはり物にもよりますが10〜20分程度はかかっておりました。
> 現在WIN2000 vb6 oracle にて開発を行っています。
>
> 現在行っている処理はテキストのデータ(固定長)を読み込み
> ワークテーブルへインサートする処理を行い、
>
> @ファイルデータ → ワークテーブル 約20分

プログラムで条件判断などの制御が必要ないなら、SQL*Loaderをお勧めします。
プログラムがトリガーであれば、バッチファイルを作っておいて(もしくはプログラムでその場で作成)起動すればよいと思います。
#結果はログファイル見ることになりますが。
時間は大幅に短縮されるはずです。
じゅでさん まどかさん お返事ありがとうございます。

やはり単純なPG修正では速くなりそうにないですね。
ちなみにテキストを取り込む際には内部的制御を掛けているので
ファイルの変換が必要になりそうですが、SQL*Loaderでもいけ
るかもしれません。

やはりそもそもVBでバッチ処理的な物はむかないのでしょうが、
他の言語と比べてどれくらいの差があるのでしょうか??
(ベンチマーク的なテストはしたことがないもので・・・)

自分でも調査してみます。 また何かわかることがあれば
お願いします。
> ちなみにテキストを取り込む際には内部的制御を掛けているので
> ファイルの変換が必要になりそうですが、SQL*Loaderでもいけ
> るかもしれません。

プログラムの役割として、SQL*Loaderの入力ファイルを出力するというのを含めればよいですね。

> やはりそもそもVBでバッチ処理的な物はむかないのでしょうが、
> 他の言語と比べてどれくらいの差があるのでしょうか??

バッチという意味では、イベントドリブンと手続きという言語性質になりますし
速さではランタイム形式なのかネイティブなのかというところだと思います。
VB6としては、言わずもがな ですね。
ただ、工夫の余地はあると思います。
既出の一気にファイルを読んだり、バイナリで扱ったり、変換という操作を最小限にしたり。
返答がおそくなってすいません。

あれから色々と調べたのですが、どうやらOracleへの
INSERT部分が遅いのではく、文字列をバイトで区切って
構造体にいれる部分で時間がかかっているみたいです。

StrConv(MidB(StrConv(BUF_LOCAL, vbFromUnicode), from, to), vbUnicode)
※上記を10回位使用して構造体に値をセットしています。

上記の記述にて文字列をバイト区切りにて取得しているのですが、
この部分を速くする方法はないでしょうか?
ちなみに開発環境(Pentium4 3.0G メモリ:525M)で実施したところ
1万件のデータを構造体に格納するのに2分40秒位かかっていました。
※構造体はグローバル変数にて宣言している。
すいません
勘違いして違う内容を投稿してしまいました。

解決とします。

申し訳ありません。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板