Laboratory of Mobile Agricultural Chemicals Searcher
携帯農薬検索実験室

研究会

  ツリー表示 ┃スレッド表示 ┃一覧表示 ┃トピック表示 ┃番号順表示 ┃検索  
80 / 114 ツリー <前へ | 次へ>

〔327〕ACFinder 060620版 kabe (06/06/20 23:21)

〔348〕Re:テーブルの構成 Hidemi Oya (06/06/24 21:56)
〔349〕Re:テーブルの構成 kabe (06/06/24 22:29)
〔350〕Re:テーブルの構成 Hidemi Oya (06/06/25 3:04)
〔352〕Re:テーブルの構成 kabe (06/06/25 15:03)
〔354〕Excel 読み込み高速化 Hidemi Oya (06/06/25 16:35)
〔355〕Re:テーブルの構成 kabe (06/06/25 16:48)
〔356〕Re:テーブルの構成 Hidemi Oya (06/06/25 18:28)
〔357〕Re:テーブルの構成 kabe (06/06/25 21:25)
〔358〕Re:テーブルの構成 Hidemi Oya (06/06/25 22:41)
〔359〕Re:テーブルの構成 Hidemi Oya (06/06/25 23:17)
〔360〕Re:テーブルの構成 kabe (06/06/26 7:03)
〔361〕Re:テーブルの構成 Hidemi Oya (06/06/26 20:53)

〔348〕Re:テーブルの構成
 Hidemi Oya WEB  (06/06/24 21:56)

引用なし
   kabe さん、こん**は。Hidemi Oya です。

>作物名だけのテーブルを農薬検査所の検索システムのHTMLソースから作って、利用できないかなと思ってますが、まだ手はつけていません。
 こちらも期待しています。

>Excelファイルの読み込みとデータベース更新部分で比較してみました。
 acis.db 新規作成で 13 秒差…。tekiyo テーブルから重複項目を抜くのは今までより処理が増えると思うんですが、それにも増して屋号カットルーチンを外した影響の方が大きいということですね。

>なお、acis.dbが存在する場合には、最初に既存のテーブルを削除する操作をしていますが、これが加わると時間差が広がります。
 DROP TABLE が加わると 32 秒差、25 %の短縮はでかいですね。それにしても、データサイズが大きいので、DROP TABLE が思いの外時間を食ってるんですねえ…。 現行バージョンで DROP TABLE の有り無しで 17 秒差、修正バージョンの DROP TABLE 有り無しで8秒差、ちょうどファイルサイズと正比例しますね。シングルファイルだからある程度はやむを得ないと思いますが、DROP TABLE にここまでかかるとは…。

 この結果を見ると、データ更新速度の向上という点では、屋号カットは kihon テーブルのみ、tekiyo テーブルから重複項目を削除するってのは、かなりおかげが大きいです。どうせなら、更新のたびにデータベース再作成ってのが良いかもしれません。今のところ、定型処理でもパーマネントビューは使う予定がないので、データベースの再作成でも OK です。
 問題は、テーブルを連結して使うことになる検索速度ですね。今までより若干遅くなりそうですが、ローカルディスクなら大丈夫でしょうか…。LAN 経由だと体感できる速度差があるかな?

>あと現状の tekiyo テーブルに tsusho フィールドが必要な理由としては、作物、病害虫検索時の通称モードでは tsusho フィールドをベースに select distinct で重複する適用を表示しないようビューを作成して検索に使用していることが上げられます。
 この話とは直接関係ありませんが…。SQLite ではあまり差を感じませんが、一般的に DISTINCT は時間がかかるので、表示行数が多くなる場合は GROUP BY を使った方が良いといわれています。

〔349〕Re:テーブルの構成
 kabe WEB  (06/06/24 22:29)

引用なし
   >Hidemi Oyaさん
kabe です。

> acis.db 新規作成で 13 秒差…。tekiyo テーブルから重複項目を抜くのは今までより処理が増えると思うんですが、それにも増して屋号カットルーチンを外した影響の方が大きいということですね。
いや、insert into するフィールド数は逆に少なくなるので、これも少しは貢献しているかもしれません。

>どうせなら、更新のたびにデータベース再作成ってのが良いかもしれません。
どうも、これが良さそうです。

> 問題は、テーブルを連結して使うことになる検索速度ですね。今までより若干遅くなりそうですが、ローカルディスクなら大丈夫でしょうか…。
体感的には、少し遅くなったような気がします。
検索部分で時間測定をしてみます。

>表示行数が多くなる場合は GROUP BY を使った方が良いといわれています。
これも試してみます。

〔350〕Re:テーブルの構成
 Hidemi Oya WEB  (06/06/25 3:04)

引用なし
   kabe さん、こん**は。Hidemi Oya です。

>いや、insert into するフィールド数は逆に少なくなるので、これも少しは貢献しているかもしれません。
 そうか、今までも Sheets[No].Strings[Row] で取り出したカンマテキストをそのまま INSERT 文の値として渡すんじゃなくて、ダブルクォートしたりするルーチンが入っていたので、フィールドを抜く処理を追加してもそれほど大きな影響はないんですね。それよりも、DROP TABLE と同様に INSERT するフィールド数が少ない方が書き込みが速くなる影響の方が大きいと…。

 ところで、現在は Excel ファイルを見えない TStringGrid か何かに一括して保存してから SQLite に書き込んでますよね? TStringGrid や TStringList は、データ数が多くなるとだんだん遅くなるので、下記のように1行読むごとに INSERT 文を発行する方式にすれば、もっと速くなりませんかね?

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ComCtrls, StdCtrls, ExtCtrls, XBiff;

type
 TForm1 = class(TForm)
  XBiff1: TXBiff;
  Button1: TButton;
  ProgressBar1: TProgressBar;
  procedure Button1Click(Sender: TObject);
  procedure XBiff1Progress(Sender: TObject; Progress: Integer);
  procedure XBiff1ReadCell(Sender: TObject; SheetNo, Row, Col,
   rgbAttr: Integer; Data: String; var Cancel: Boolean);
  procedure XBiff1ReadSheetName(Sender: TObject; SheetName: String);
 private { Private 宣言 }
  FValidSheet: boolean;
  FRow: TStringList;
  procedure InsertRow;
 public { Public 宣言 }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

function HanToZen(s: string): string;
begin
 // 実際には変換ルーチンが入る
 Result := s;
end;

procedure TForm1.InsertRow;
var
 sql: string;
begin
 if FRow.Text = '' then Exit;
 sql := 'INSERT INTO tekiyo VALUES(' + FRow.DelimitedText + ')';
 FRow.Clear;
 // ここで SQLite に INSERT 文発行
end;

// Excel ファイル読み込み&SQLiteに保存
procedure TForm1.Button1Click(Sender: TObject);
begin
 FRow := TStringList.Create;
 try
  FRow.QuoteChar := '''';
  ProgressBar1.Position := 0;
  XBiff1.LoadFile('test.xls');
  InsertRow; // 最後の行を保存
 finally
  FRow.Free;
 end;
end;

procedure TForm1.XBiff1Progress(Sender: TObject; Progress: Integer);
begin
 ProgressBar1.Position := Progress;
end;

procedure TForm1.XBiff1ReadSheetName(Sender: TObject; SheetName: String);
begin
 FValidSheet := SheetName = '登録適用部';
end;

procedure TForm1.XBiff1ReadCell(Sender: TObject; SheetNo, Row, Col,
 rgbAttr: Integer; Data: String; var Cancel: Boolean);
begin
 if not FValidSheet then Exit;
 if Row = 0 then Exit;
 case Col of
  5..8, 13, 18: FRow.Strings[Col - 4] := AnsiToUtf8(AnsiQuotedStr(HanToZen(Data), '"'));
  9..12, 14..17: FRow.Strings[Col - 4] := AnsiToUtf8(AnsiQuotedStr(Data, '"'));
  20..24: FRow.Strings[Col - 5] := AnsiToUtf8(AnsiQuotedStr(Data, '"'));
  0: begin
   InsertRow; // 前の行を保存
   FRow.DelimitedText := Data + ',"","","","","","","","","","","","","","","","","","",""';
  end;
 end;
end;

end.

〔352〕Re:テーブルの構成
 kabe WEB  (06/06/25 15:03)

引用なし
   >Hidemi Oyaさん
kabe です。

> ところで、現在は Excel ファイルを見えない TStringGrid か何かに一括して保存してから SQLite に書き込んでますよね?
Excel入出コンポのサンプルどおり、TStringListに全部読み込んだ後に、SQLite に書き込んでいます。
正確にはSQLite に書き込む前に、列数をそろえるため(使用回数1〜5が行ごとに異なるため)もう1回StringListのCount分ループを回しています。

>TStringGrid や TStringList は、データ数が多くなるとだんだん遅くなるので、下記のように1行読むごとに INSERT 文を発行する方式にすれば、もっと速くなりませんかね?
ちょっと、試してみましたが、どうもうまくいきません。
ReadCellイベントでうまくデータが拾えず挫折しています。(;_;
もちろん、[#350]のままのコードではないので、どこか不具合あるのだと思いますが、うまく動かすにはちょっと時間がかかりそうです。

ただ Excel の読み込み処理に一番時間がかかっているので、もう少し改善できないか取り組んでみます。
>FRow.DelimitedText := Data + ',"","","","","","","","","","","","","","","","","","",""';
0列目で最初に列数分、初期化すればいいんですね。
このあたり、参考になりそうです。

〔354〕Excel 読み込み高速化
 Hidemi Oya WEB  (06/06/25 16:35)

引用なし
   kabe さん、こん**は。Hidemi Oya です。

>Excel入出コンポのサンプルどおり、TStringListに全部読み込んだ後に、SQLite に書き込んでいます。
 TStringList は、件数が増えると Add が目に見えて遅くなります。データの行データを全て読み込むのはちょっときついです。1行分の列データを保存する程度なら、それほど遅くありません。
 ってことで、1行分のデータを読み込むたびに INSERT 文を発行した方が高速化できる可能性が高いです。

>ReadCellイベントでうまくデータが拾えず挫折しています。(;_;
 私も細かくは検証していませんが、それなりに問題なさそうに思えましたが…。具体的に、どのようなデータが読めないのでしょう?
 サンプルだと、Col = 0 の時に行が変わったと判断して INSERT 文を発行していますが、Col = 0 にデータがない場合は、これだとダメですね。適用データは必ず登録番号があるのでこれでも大丈夫だと思いますが、Row 番号をメモリに保存しておいて、その値と現在の Row 番号が異なったら INSERT 文を発行する方が確実です。

>>FRow.DelimitedText := Data + ',"","","","","","","","","","","","","","","","","","",""';
>0列目で最初に列数分、初期化すればいいんですね。
 最初は OnReadCell イベントが発生するたびに単純に Add してたんですが、これだと列番号とデータが合いませんでした。それで、セルにデータがない時は OnReadCell イベントが発生しないことに気が付いた次第です(^_^;)。で、先にデータ領域を用意しておく方法として、これが最も単純な方法かなあと…。
 string の配列を用意しておいても良いのですが、あとでクォート付きカンマテキストに変換することを考えると、TStringList を使った方が楽ですから(速度的には不利になるかもしれませんが)。QuoteChar をシングルクォートにしておいて、CommaText ではなく Delimited テキストを使用することにより、空白データもそのまま初期化できますし…。なお、整数データの部分は、ダブルクォートなしにすれば OK です。

〔355〕Re:テーブルの構成
 kabe WEB  (06/06/25 16:48)

引用なし
   >Hidemi Oyaさん
kabe です。

> 問題は、テーブルを連結して使うことになる検索速度ですね。今までより若干遅くなりそうですが、ローカルディスクなら大丈夫でしょうか…。
テスト版を作成してみました。
http://acfinder.kabe.info/acfinder_060625_test.lzh
acis.db を1回削除してからデータ更新してください。
acis.db を消すと、ダイアログがうざいですが、ここは改良の余地ありです。(^^;
体感的にはそれほど、変わりないかなという気もします。
これで実用になりそうなら、この方式に変更します。
実テーブルは
kihon
m_kihon
m_tekiyo
の3つです。
m_kihon は登録番号をプライマリーキーにしたテーブルです。
従来の tekiyo は同一のフィールドでビューになっています。

〔356〕Re:テーブルの構成
 Hidemi Oya WEB  (06/06/25 18:28)

引用なし
   kabe さん、こん**は。Hidemi Oya です。

>体感的にはそれほど、変わりないかなという気もします。
 定型処理で結構複雑な表を作っても、ローカルディスクなら特に違和感はありません。[#353] で書いた方法と比べてみたら、明らかに分かるくらい実テーブルを使う方が速いです。

>これで実用になりそうなら、この方式に変更します。
 ってことで、成分がない kihon テーブルは、ビューを使うよりこの方式の方が良いですね。
 できれば、tekiyo ビューに「剤型」も追加してもらえると、定型処理で使いやすくなります(種類で like を使わなくてすみますから)。作物・病害虫タブでも、剤型による絞り込みができると便利なことが多いですし(特に水田主体の農家に対応する時など)。

 データベース作成も、私の環境(Barton 3200+ + 512MBx2 DualDDR400)で 00:01:17 でした。体感的にかなり速くなったと感じます。
 が、金曜日に事務所のメモリ 256MB のノートで前のバージョンを実行した時は、私が使っている 768MB のノートに比べてかなり遅かったような気がします。TStringList に全部読み込む方法だと、メモリサイズ及びアクセス速度の影響がもろに出るのだと思います。かなり速くなったとはいえ、[#352] の方法への転換が望まれます。
 それはそれとして、まだ試してませんが、データベースサイズが小さくなった分、もしかすると LAN 経由でも従来バージョンより速くなるかもしれませんね。

 [#353] 方式を試す時に気が付きましたが、今バージョンでは CREATE TEMP VIEW とかでダイアログボックス出なくなりましたね。ただ、SQL 分をセミコロンで区切って複数書いても、実行されるのは最初の文だけでしょうか? 前は、複数実行されたような気がしましたが…。

 定型処理のアップグレードに対応しやすくするため、現在 SQLite3.pas と SQLitTable3.pas を regexp 演算子に対応できるように修正しています。動作チェック環境が欲しいので、ACFinder のソースをメールしてもらえませんか?

〔357〕Re:テーブルの構成
 kabe WEB  (06/06/25 21:25)

引用なし
   >Hidemi Oyaさん

kabe です。

> できれば、tekiyo ビューに「剤型」も追加してもらえると、定型処理で使いやすくなります(種類で like を使わなくてすみますから)。
http://acfinder.kabe.info/acfinder_060625_test.lzh
剤型追加版に置き換えました。

ソースの方は、少しお待ちください。

〔358〕Re:テーブルの構成
 Hidemi Oya WEB  (06/06/25 22:41)

引用なし
   kabe さん、こん**は。Hidemi Oya です。

>http://acfinder.kabe.info/acfinder_060625_test.lzh
>剤型追加版に置き換えました。
 exe ファイルのタイムスタンプが変わってないので「あれ?」っと思ったんですが、
pramga table_info(tekiyo);
で確認したら、やっぱり前のテストバージョンと同じです。
 ちなみに、今回のデータ更新時間は、00:01:19 で acis.db を削除した場合とほとんど変わりませんでした。テストバージョンは、すでに更新のたびにデータベース再作成方式になってるんでしょうか?

 あとは、m_kihon テーブルに seibun1, seibun2, ..., seibun5 フィールドが追加されて、tekiyo ビューが seibun1, kaisu1, seibun2, kaisu2, ..., seibun5, kaisu5 てな具合にフィールドが並んでくれると、入手可能なデータから作成可能なテーブルとしてはもう完璧ですね。

>ソースの方は、少しお待ちください。
 了解です。今はまだ SQLite3.pas と SQLiteTable.pas に必要な関数を追加している段階なので(sqlite3.dll のソースと首っ引きです^^;)、それほど急ぐわけでもありません。

〔359〕Re:テーブルの構成
 Hidemi Oya WEB  (06/06/25 23:17)

引用なし
   kabe さん、こん**は。Hidemi Oya です。

 書き忘れてましたが、「剤型」も半角→全角変換するようにしてください。

〔360〕Re:テーブルの構成
 kabe WEB  (06/06/26 7:03)

引用なし
   >Hidemi Oyaさん
kabe です。

>で確認したら、やっぱり前のテストバージョンと同じです。
すいません。
FTPしたと思ったのですが、されてなかったようです。(^^;
更新しました。

> ちなみに、今回のデータ更新時間は、00:01:19 で acis.db を削除した場合とほとんど変わりませんでした。テストバージョンは、すでに更新のたびにデータベース再作成方式になってるんでしょうか?
いや、まだです。

〔361〕Re:テーブルの構成
 Hidemi Oya WEB  (06/06/26 20:53)

引用なし
   kabe さん、こん**は。Hidemi Oya です。

>更新しました。
 今度は OK です。剤型も全角に変換していただき、ありがとうございます。

>いや、まだです。
 事務所で使っている CeleronM 1.7?GHz DDR2-533 768MB で、db 新規作成 00:01:57、更新 00:02:07 でした。環境による差が大きいですね。INSERT は、メモリだけでなく CPU にもかなり依存しそうです。DROP TABLE に要する時間は、CPU と HDD かな?

  ツリー表示 ┃スレッド表示 ┃一覧表示 ┃トピック表示 ┃番号順表示 ┃検索  
80 / 114 ツリー <前へ | 次へ>
ページ:  ┃  記事番号:   
(SS)C-BOARD vv3.8 is Free.