[リストへもどる]
一括表示

投稿時間:2004/02/25(Wed) 22:11
投稿者名:竜牙
URL :
タイトル:
ファイル処理の高速化
こんばんは、はじめまして。竜牙と申します。
現在駆け出しのプログラマーをしておりまして、
こちらのHPには学生のころからお世話になっております。

実は折り入ってお聞きしたいことがござまして、掲示板の方
に書き込みをさせていただかせていただきました。

ファイルの処理の高速化についてなのですが、ループで何十万
件もあるファイルを読み込みテーブルに挿入する、という処理
をする場合下記以外にどのような方法がございますでしょうか?

開発環境はWindows2000とSQLServerです。
スペックについては・・・・すみません、詳しくは解りませんがあまり
良い方ではないです。

ファイルの形態は以下の通りです。
同一アルファベットが項目の文字列です。
AAABBBBBBBCCDDEEEEEEEEGGHHHHHHHHIIIIIIII(リターンコード)
AAABBBBBBBCCDDEEEEEEEEGGHHHHHHHHIIIIIIII(リターンコード)
AAABBBBBBBCCDDEEEEEEEEGGHHHHHHHHIIIIIIII(リターンコード)
AAABBBBBBBCCDDEEEEEEEEGGHHHHHHHHIIIIIIII(リターンコード)



(A:Code1 B:Code2 C:Code3 D:Code4
E:Date1 G:Code5 H:Comment I:Date2)

以下が自分なりに組んでみた処理のソースです
(RSは ADODB RecordSet で、ConectionはすでにOpenした後と
考えてください)

1:インプットファイルで項目ごとデータを読み出す
   strFileName = "E:\File.DAT"
   intFileNum = FreeFile

    Open strFileName For Input As #intFileNum

        Do Until EOF(intFileNum)
  
                Code1 = Input(3, #intFileNum)
                Code2 = Input(7, #intFileNum)
                Code3 = Input(2, #intFileNum)
                Code4 = Input(2, #intFileNum)
                Date1 = Input(8, #intFileNum)
                Code5 = Input(2, #intFileNum)
                Comment = Input(8, #intFileNum)
                Date2 = Input(8, #intFileNum)
                Returns = Input(2, #intFileNum)
        
        
            strA = "INSERT INTO Table " _
                 & "VALUES ( '" & Code1 & "','" _
                 & Code2 & "','" _
                 & Code3 & "','" _
                 & Code4 & "','" _
                 & Date1 & "','" _
                 & Code5 & "','" _
                 & Comment & "','" _
                 & Date2 & "')"
            
            Conection.Execute strA, , adCmdText            
       Loop
    
    Close #intFileNum
    RS.Close
    Set RS = Nothing

2:Getで値を取得する
   strFileName = "E:\File.DAT"
    intFileNum = FreeFile
                
    RS.Open "SELECT * FROM Table",cn
    
    Code1 = String(3, " ")
    Code2 = String(7, " ")
    Code3 = String(2, " ")
    Code4 = String(2, " ")
    Date1 = String(8, " ")
    Code5 = String(2, " ")
    Comment = String(8, " ")
    Date2 = String(8, " ")
    Returns = String(2, " ")

    Open strFileName For Binary As #intFileNum
    Do Until EOF(intFileNum)

        strB = Space(42)
        Get #intFileNum, , strB
        Code1 = Mid(strB, 1, 3)
        Code2 = Mid(strB, 4 ,7)
        Code3 = Mid(strB, 11, 2)
        Code4 = Mid(strB, 13, 2)
        Date1 = Mid(strB, 15, 8)
        Code5 = Mid(strB, 23, 2)
        Comment = Mid(strB, 25, 8)
        Date2 = Mid(strB, 33, 8)
        Returns = Mid(strB, 41)
          
        RS.AddNew
            RS!Code1 = Code1
            RS!Code2 = Code2
            RS!Code3 = Code3
            RS!Code4 = Code4
            RS!Date1 = Date1
            RS!Code5 = Code5
            RS!Comment = Comment
            RS!Date2 = Date2
        RS.Update
        
    Loop
    Close #intFileNum
    
    RS.Close
    Set RS = Nothing

この1,2の方法で20万件のデータを処理しましたところ
平均5分(300秒)という処理速度でした。
この方法よりも早くファイルを処理できる方法はありませんでしょうか。
ここをこうした方がはやくなるのでは、という意見でも、
こういう処理方法がある、という意見でもかまいません。
どうかご意見の方、よろしくお願い致します。

長くなってしまってすいませんでした。

投稿時間:2004/02/26(Thu) 08:06
投稿者名:nobu
Eメール:
URL :
タイトル:
Re: ファイル処理の高速化
> こちらのHPには学生のころからお世話になっております。

...ならば、こちらのHPにあるファイル関係には目を
通していると思いますが、それらは試されたのでしょうか?

Do 〜  Loop より For 〜 Next の方が速いとか。
Open strFileName For Input As #intFileNum にての
入力ファイルの総行数を調べて(このHPのFileSystemObject オブジェクト関係)
Do 〜  Loop を For 〜 Next に変えたら所要時間はどう変わりますか?

また、提示されたと別のやり方の1案としては
(実行速度の差は調べてはいませんが案としてです)

2:Getで値を取得する の方は

> AAABBBBBBBCCDDEEEEEEEEGGHHHHHHHHIIIIIIII(リターンコード)

1行の文字数が同じ(固定)なら

ユーザー定義型で
Type InType    
  A   As String * 3
  Code1 As String * 7

...とかとしたら如何でしょうか?

どちらにしても再度このHPの「ファイル操作関係」も確認して下さい。

投稿時間:2004/02/26(Thu) 14:55
投稿者名:GOD
Eメール:
URL :
タイトル:
Re: ファイル処理の高速化
下のリンクが参考になるかも。
http://www7.big.or.jp/~pinball/discus/sqls/23376.html

#私のところにSQL Serverが無いので確かめていません。

投稿時間:2004/03/01(Mon) 21:46
投稿者名:竜牙
Eメール:
URL :
タイトル:
解決: ファイル処理の高速化
遅くなってしまい、大変申し訳ございません。
nobuさん、GODさん。お二人ともどうもありがとうございました。

ファイルシステムオブジェクトで全体の件数をゲット、さらにユーザー宣言を
使用してファイルを4万件ずつ分割し、SQLで一括挿入するようプログラムを書
き換えましたところ、平均5分(300秒)の処理が平均たったの20秒で処理する
ことができました。
20万件をいっぺんに処理するのは処理的に少々不安で、ファイルを分割しまし
たが・・・・。

ご助力、本当にありがとうございました。
今後もよろしくしていただけましたら、幸いです。