DB 大量output 時に SELECT やLOCATE の負荷が心配です。

462 views
Skip to first unread message

fushi...@leto.eonet.ne.jp

unread,
Feb 2, 2021, 3:40:54 AM2/2/21
to radstu...@googlegroups.com

Letoと申します。

いつもお世話になります。皆様ありがとうございます。

 

Database(Firebird)Delphiで扱う時、

もしかしたら、とんでもない負荷がかかっているのか?

迷って先に進めないことがあります。(CPUやメモリ使用量を見てもハッキリしません)

ずーっと1人で開発しているので、アドバイスなど頂ける先輩もいません。

 

たいへん稚拙で申し訳ございませんが、皆様、どうかご教授いただければ幸いです。

 

例えばですが、

ネット経由のRPA自動で、delphi で作成した(exe)を稼働させます。

CSVファイル(200件)を → Database insert する処理をしたいと思います。

この時、Databaseを参照し項目を取り出したい、

また、

同じKEY項目のレコードがoutputするDatabaseにあるかもどうかも判断したい。

 

このような場合、200回のoutput selectLocateFindなどを繰り返す事となります。

私は、

Databaseへのoutput方法は TIBTable を使い CachedUpdates で最後に ApplyUpdates しています。

この時、

同じKEY項目のレコードがoutputするDatabaseにあるかもどうか? 

Databaseを参照し項目を取り出す時、

SELECTはとても負担がかかり、なんどもSELECTしてはいけないように思います。

Find Locate を使うのでしょうか?
配列に読み込んで参照するのがよいのでしょうか? 

 

ずーっと悩んでいたのですが、RPAで自動に実行されてしまう事を思うと・・・

不安で夜も眠れません。

 

本当に、たいへん稚拙で申し訳ございませんが

皆様、どうかよろしくお願いいたします。

 

 

 

info syari

unread,
Feb 2, 2021, 4:03:08 AM2/2/21
to radstu...@googlegroups.com
見当違いならすみません。 すでに離れて久しいのですが、
TIBSQLやTIBQueryなどを用いてSQLを利用してはいかがですか?

TIBTableは全権対象にしたと記憶しているので時間がかかるかと思いますが、SQLを利用したら対象データのみになるため負荷は少なくなるはずです。

SELECT、Inset, Updateで事足るかと

2021年2月2日(火) 17:40 <fushi...@leto.eonet.ne.jp>:
--
このメールは Google グループのグループ「Japan RAD Studio User Group」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには radstudio-jp...@googlegroups.com にメールを送信してください。
このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/radstudio-jp/000c01d6f93f%241bfdc4c0%2453f94e40%24%40leto.eonet.ne.jp にアクセスしてください。

fushi...@leto.eonet.ne.jp

unread,
Feb 2, 2021, 4:09:23 AM2/2/21
to radstu...@googlegroups.com

早速のご返答、本当にありがとうございます。

DBに対して insert update select を多発(何度も発行)しても大丈夫なのですか?

例えば、1000件のデータに対して行っても良いのでしょうか?

サーバへの負荷はかかりませんか?

 

どうぞよろしくお願いいたします。

このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/radstudio-jp/CAFeF7J%3D_44GFksnJ0_2x73R1wfEyL8K2fMgBas2GVEd5Raty3g%40mail.gmail.com にアクセスしてください。

fushi...@leto.eonet.ne.jp

unread,
Feb 2, 2021, 4:22:14 AM2/2/21
to radstu...@googlegroups.com

Leto と申します。

 

申し訳ございません、説明不足でした。

質問し直します。よろしくお願いいたします。

TIBSQL使った事ありませんでた、使ってみます!

ありがとうございます!

 

そこで、1レコードoutputする処理する際に、毎回

TIBQqery を使って SELECTLocateを多発してもだいじょうぶですか?

よろしくお願いいたします。

 

 

 

 

 

From: radstu...@googlegroups.com <radstu...@googlegroups.com> On Behalf Of info syari
Sent: Tuesday, February 2, 2021 6:03 PM
To: radstu...@googlegroups.com
Subject: Re: [radstudio-jp:188] DB
大量output 時に SELECT LOCATE の負荷が心配です。

 

見当違いならすみません。 すでに離れて久しいのですが、

このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/radstudio-jp/CAFeF7J%3D_44GFksnJ0_2x73R1wfEyL8K2fMgBas2GVEd5Raty3g%40mail.gmail.com にアクセスしてください。

info syari

unread,
Feb 2, 2021, 7:40:58 AM2/2/21
to radstu...@googlegroups.com
Select でキー指定で読めば直接あるなし【BOF,EOFのチェック】で判明しますからロケートはいらない【というか私は使ったことがない】と思いますけど

1000のオーダーでもさほど負荷を感じたことがないです。 サーバーの規模にもよるんでしょうが。

憶件数を持つDBでもSQLとキーの持ち方ですぐに結果出ましたよ。 

2021年2月2日(火) 18:22 <fushi...@leto.eonet.ne.jp>:
このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/radstudio-jp/001e01d6f944%24e2579010%24a706b030%24%40leto.eonet.ne.jp にアクセスしてください。

ML-Sasaki

unread,
Feb 2, 2021, 9:38:54 AM2/2/21
to radstu...@googlegroups.com
手段としては大丈夫です。Select・Update・Insertは標準的な手段でDB操作の基本です。
TIBTableなどは初心者が利用しやすいようにDB操作を隠ぺいしていますが、内部では Select・Update・Insertを
使用して(もっとダイレクトですが)DBを操作しています。
ちなみにTIBQueryよりTIBSQLのほうがよりシンプルで処理が早いですがその分扱いにくいです。

負荷的に大丈夫かどうかは、DBの定義・データ件数・インデックスの状態、そのジョブを実行しているときの
サーバーの負荷状態やハードの性能や構成に左右されますし、そもそも許容範囲がわからないので「大丈夫か?」
と問われても返答できる方はいないと思います。
これが「もっと負荷のかからない、処理方法はありますか?」という質問なら、もっと反応があると思います。

不明な点が多すぎるのであくまで参考意見ですが、1000件程度のインサートであれば前に回答がありましたように
TIBDatabaseとTIBQuery利用で、CSVファイルはTStringListなどに読み込み、ループで回しながら キー値で Select
して、EOFならばインサートし EOFでなければ更新すればよいと思います。
(重複不可のキーでしょうから読み込みは1件か0件です。Locateはありません。)
注意点は、SelectのSQL文はパラメータを使用して、TIBSQLにSQL文をセットしたらPrepareすることと、
CashUpdateを使用せず、Transactionを使用してループ処理完了後Commitし、例外発生したらRollbackすることで
しょうか?

ほかの方法としては、DBにワーク用のテーブルを作成して挿入するデータを一括でインサートすればSQL文だけで
DB内で処理完結できると思いますが、私も実際にやったことがないので参考情報程度にしておいてください。
挿入するレコード数が数万件あるとかで対策に困ったら、Firebird関連のサークルのほうで質問してみる価値は
あるかと思います。

不安なお気持ちは察しますが、どんな方法をとっても実際の状況が確認できなければ不安は消えないと思います。
テストと評価は事前に行う必要があると思います。
実際に不具合が発生していないなら大丈夫でしょうし、1000件程度のデータなら、対象のテーブルのレコード数が
数万件以上でキーにインデックスがないとかDBサーバーやクライアントPCがメモリ不足でない限り、TIBTable
でもTIBQueryでもそんなに差はないと思いますが、SQL文は覚えて損はありませんからやってみる価値はあると思ます。


2021年2月2日(火) 18:22 <fushi...@leto.eonet.ne.jp>:
このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/radstudio-jp/001e01d6f944%24e2579010%24a706b030%24%40leto.eonet.ne.jp にアクセスしてください。

fushi...@leto.eonet.ne.jp

unread,
Feb 3, 2021, 12:19:18 AM2/3/21
to radstu...@googlegroups.com

Leto です。

皆様ありがとうございます。

いろいろ状況の説明不足で申し訳ございませんでした。

Database (膨大でない)に対してInsert, update, select 繰り返してもさほど問題は無い。

わざわざ、TIBTableで CashUpdate を使用しても意味はない。

安心いたしました。感謝いたします。

 

アドバイス頂いた中で、出来てないことが2点ありました。

>>ループ処理完了後Commitし、例外発生したらRollbackすることでしょうか?

 

例外発生でも Rollbackせず、そのまま終了させていました。

 

>>1000件程度のデータなら、対象のテーブルのレコード数が

数万件以上でキーにインデックスがないとかDBサーバーやクライアントPCがメモリ不足でない限り、TIBTable

でもTIBQueryでもそんなに差はないと思います

 

インデックスキー付けていませんでした。

利点がわかっていませんでした、検索がはやくなるのですね!

レコード数が多いので検討してみたいいのですが、デメリットもあるのですね!

キー以外の他の項目でSELECTをかける事も多く

今のところ1万件以下なのですが、将来的にどうしようか、悩みます。

 

 

本当に大変!勉強になりました。

感謝いたします、みなさま!ありがとうございました。

このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/radstudio-jp/CA%2BK32GJV8Pih2kM4GvzKKBzAjbJnBBn_Y%2BSGJi6pRzfN9X%3Dp9A%40mail.gmail.com にアクセスしてください。

赤推

unread,
Feb 3, 2021, 12:56:09 AM2/3/21
to radstu...@googlegroups.com
赤推です。

私はほとんどオラクルですが、RDBMSであれば基本は変わらないということで。
あくまでも私個人の感覚でお答えします。

RDBMSではまずLocateやFindなどは使いません。outputというのか何なのかわかりませんが。あとTTableとかTなんとかTableなども使いません。あくまでも私の場合ですが。
ほどんどTQueryとかですね。最近はTFDCommandなども使います。
例えばキー項目でデータベース側で制約があるとして(プライマリーキーであるとかユニークキーであるとか)、オラクルで1,000件のCSVデータをデータベースにInsertしたいときは、TABLE_Aというテーブルの項目Aがキーとして、

BEGIN
INSERT INTO TABLE_A(A,B,C) VALUES(:A,:B,:C);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
UPDATE TABLE_A SET B=:B,C=:C WHERE A=:A;
WHEN OTHERS THEN
RAISE;
END;

というSQLをTQueryにセットして、1,000回実行しています。これはすでにキーが重複するデータが有る場合は、BとCを更新するという処理です。
こういう感じでやれば、Delphiの処理は最低限になって、バグが発生しにくいです。
これはオラクルのSQLですが、Firebirdでも同様のものはSQLで書けると思います。

あと負荷を気にされているようですが、回線の太さを多少考慮するにしても、1,000件くらいはほとんど考えなしに実行します。全然大したことはないです。


赤推
>> jp+unsu...@googlegroups.com にメールを送信してください。
>> このディスカッションをウェブ上で閲覧するには [a:https://groups.google.com/d
>> /msgid/radstudio-jp/000c01d6f93f%241bfdc4c0%2453f94e40%24%40leto.eonet.ne.
>> jp?utm_medium=email&utm_source=footer]https://groups.google.com/d/msgid/
>> radstudio-jp/000c01d6f93f%241bfdc4c0%2453f94e40%24%40leto.eonet.ne.jp にア
>> クセスしてください。
>
>--
>このメールは Google グループのグループ「Japan RAD Studio User Group」に登録し
>ているユーザーに送られています。
>このグループから退会し、グループからのメールの配信を停止するには radstudio-jp
>+unsub...@googlegroups.com にメールを送信してください。
>このディスカッションをウェブ上で閲覧するには [a:https://groups.google.com/d/
>msgid/radstudio-jp/CAFeF7J%3D_44GFksnJ0_2x73R1wfEyL8K2fMgBas2GVEd5Raty3g%
>40mail.gmail.com?utm_medium=email&utm_source=footer]https://groups.google.com
>/d/msgid/radstudio-jp/CAFeF7J%3D_44GFksnJ0_2x73R1wfEyL8K2fMgBas2GVEd5Raty3g%
>40mail.gmail.com にアクセスしてください。
>
>--
>このメールは Google グループのグループ「Japan RAD Studio User Group」に登録し
>ているユーザーに送られています。
>このグループから退会し、グループからのメールの配信を停止するには radstudio-jp
>+unsub...@googlegroups.com にメールを送信してください。
>このディスカッションをウェブ上で閲覧するには [a:https://groups.google.com/d/
>msgid/radstudio-jp/001e01d6f944%24e2579010%24a706b030%24%40leto.eonet.ne.jp?
>utm_medium=email&utm_source=footer]https://groups.google.com/d/msgid/
>radstudio-jp/001e01d6f944%24e2579010%24a706b030%24%40leto.eonet.ne.jp にアク
>セスしてください。

fushi...@leto.eonet.ne.jp

unread,
Feb 3, 2021, 2:02:17 AM2/3/21
to radstu...@googlegroups.com
Letoです。お世話になります。

赤推さま、ありがとうございます。
目から鱗です、インデックスがあればですよね???
Insert (update)もselect一度に処理ができるのですね!
勉強になりました。感謝いたします。
このメールは Google グループのグループ「Japan RAD Studio User Group」の登録者に送られています。
このグループから退会し、グループからのメールの配信を停止するには radstudio-jp...@googlegroups.com にメールを送信してください。
このディスカッションをウェブ上で閲覧するには、https://groups.google.com/d/msgid/radstudio-jp/A2D6F9F141D02103EDCC52%40gmail.com にアクセスしてください。

Hiroaki Kitahata

unread,
Feb 3, 2021, 2:34:10 AM2/3/21
to radstu...@googlegroups.com
こんにちは。
北畑と申します。

> Insert (update)もselect一度に処理ができるのですね!
Firebird では(version 2.1 以降ですが)、
update or insert という構文があります。
レコードがあれば update、無ければ insert を行うものです。

詳細は公開されていますので、検索してみてください。

--
Hiroaki Kitahata <kita...@wingcomputer.com>

fushi...@leto.eonet.ne.jp

unread,
Feb 3, 2021, 3:08:13 AM2/3/21
to radstu...@googlegroups.com
Letoです。

北畑さま ありがとうございます。
>Firebird では(version 2.1 以降ですが)、
>update or insert という構文があります。
>レコードがあれば update、無ければ insert を行うものです。
またまた、目から鱗です。
シンプルでわかりやすいです!!
最後に matching (キー項目) を付けるのですね。
今まで、insert(update,) select を繰り返すのはどうかと思い、
配列に読み込んでループで回したり
Ttableの CachedUpdatesを使ったら、負荷が低いのではないか・・・とか
いろいろ悩んでいました。
RPAでの データ更新作業が加わる事になり、
心配で心配で夜も寝られませんでした。

安心しました!

みなさま!お世話になりました。
ありがとうございました。
--
このメールは Google グループのグループ「Japan RAD Studio User Group」の登録者に送られています。
このグループから退会し、グループからのメールの配信を停止するには radstudio-jp...@googlegroups.com にメールを送信してください。
このディスカッションをウェブ上で閲覧するには、https://groups.google.com/d/msgid/radstudio-jp/20210203163406.B803.7DD85711%40wingcomputer.com にアクセスしてください。
Reply all
Reply to author
Forward
0 new messages