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

研究会

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

〔730〕CSV 形式の農薬登録情報ダウンロードサービスを開始しました Hidemi Oya (07/11/17 22:46)

〔752〕Re:ACFinder 071121test版 kabe (07/11/22 20:35)
〔754〕Re:ACFinder 071121test版 Hidemi Oya (07/11/23 1:11)
〔756〕Re:ACFinder 071121test版 kabe (07/11/23 9:10)
〔759〕Re:ACFinder 071121test版 Hidemi Oya (07/11/23 11:22)

〔752〕Re:ACFinder 071121test版
 kabe WEB  (07/11/22 20:35)

引用なし
   >Hidemi Oyaさん

kabe です。

> でも、前から BEGIN/COMMIT が機能してないようには感じてます。
あ〜、どうもそのようですね。
BeginTransaction と Commit をコメントアウトしても、同じ早さです。
こんなことに今頃、気付くとは…
こうなると私にはさっぱりわかりません。

〔754〕Re:ACFinder 071121test版
 Hidemi Oya WEB  (07/11/23 1:11)

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

>BeginTransaction と Commit をコメントアウトしても、同じ早さです。
 ですよね。BEGIN 文でオートコミットは中止されるはずですが、それが機能していない(たとえば、sqlite3_finalize API の呼び出しでオートコミットに戻ってるとか)か、オートコミットによる速度差がないのかのどちらかでしょう。

 前者の場合は、複数の SQL 文をまとめて発行すれば、改善される可能性はあります。とりあえずは、100〜1000 行程度の INSERT 文をまとめて ExecSQL する方法を試してみてもらえませんか?
 INSERT 文をまとめるのは、TStringList.Add() して行くのが手っ取り早いですが、行数が増えるにつれてどんどん遅くなります。string に連結して行く方がより効果的だと思います。

〔756〕Re:ACFinder 071121test版
 kabe WEB  (07/11/23 9:10)

引用なし
   >Hidemi Oyaさん

kabe です。

> とりあえずは、100〜1000 行程度の INSERT 文をまとめて ExecSQL する方法を試してみてもらえませんか?
これ、string に連結する方法を試してみたのですが、返って遅くなりました。
1000行連結すると、5倍くらい遅くなります。
文字列を連結するよりは1行づつ INSERT した方がずっと早いです。

sqlite.pas の方で何か対策ありますか。

ここの一番最後のあたり、それらしいことを書いてあるような気がしますが私には理解できません。
http://hp.vector.co.jp/authors/VA002803/sqlite/capi3dll.htm

〔759〕Re:ACFinder 071121test版
 Hidemi Oya WEB  (07/11/23 11:22)

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

>これ、string に連結する方法を試してみたのですが、返って遅くなりました。
>1000行連結すると、5倍くらい遅くなります。
 あちゃ〜、そんなに遅くなりますか…。文字列サイズが大きくなるとメモリの再割り当てが発生するので、最初に SetLength で十分な量のメモリを確保しておかなければならないのかもしれません。それと、もし INSERT 文を
 INSERT INTO table (..) VALUES (..);
にしているなら、
 INSERT INTO table VALUES (..);
にすればいくらか速くなるかも…。
 が、SQL が長すぎて sqlite3_prepare に時間がかかっているのだとすれば、上記対策をしても結果は同じでしょうね。10〜50 行程度でまとめた方が良いかもしれません。

>ここの一番最後のあたり、それらしいことを書いてあるような気がしますが私には理解できません。
 SQLite.pas の ExecSQL は、sqlite3_exec ではなく、sqlite3_prepare, sqlite3_setp, sqlite3_finalize を使っています。ということで、INSERT 文の連結でなんとかなるかなと思ったわけです。
 INSERT 文の連結でダメなら、紹介していただいた記事でやっているように、仮パラメータの INSERT 文を用意しておいて、実パラメータを bind していく方法くらいしかありません。が、SQLite には SQL 文に PREPARE/BIND がないので、API レベルで汎用的に実装する方法が思い浮かびません。それと、フィールドごとに分解して bind する処理に時間がかかりますから、今回のように CSV データを INSERT する場合は、前述のように単純に全フィールドを INSERT していく方が速いはずです。

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