- - PR -
コミット間隔
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-05-20 01:33
仮に変数名を trn1 に変えたとして
となりますが、このあたりの構造に問題があります。 「trn.Commit()」の行でコミットしているトランザクションは、 ループの外で宣言したトランザクション(trn)であって、trn1 ではありません。 ですから、trn1 はどこでもコミットされないことになります。 ですから、101レコード目の処理で、(trn1 がコミットされないまま) 新しいトランザクションを開始しようとしてエラーになっているものと思われます。 ループの外でトランザクションを開始するのをやめて、 以下のような構造にしたほうが、見やすいし、間違いがないと思います。
未検証なので、細かいミスあったらすみません。 | ||||||||||||
|
投稿日時: 2007-05-20 11:49
KIさん、ご回答ありがとうございます。
大変分かりやすい、サンプルコードを御提示いただきありがとうございます。 コミット間隔制御が実現できました。 本当にありがとうございました。 また何かありましたらお願い致します。 | ||||||||||||
|
投稿日時: 2007-05-20 11:54
> じゃんぬねっとさん、ご質問ありがとうございます。
> 一定間隔にしたい理由は、性能問題です。 > CSVのレコード件数が10万件存在するとした場合、 > 1レコード読み取り→SQL→コミット > のサイクルを10万回繰り返すのではなく、 > 1レコード読み取り→SQLを100回繰り返し、1回コミット > のサイクルを1000回繰り返したほうが性能がよいと考えられるからです。 > (実際試したわけではないので、保証はできませんが。。。) じゃんぬねっとさんが言いたいのは、10万件繰り返し→1回コミット ということなのでは? 10万件繰り返ししないで1回で10万件更新できればもっと良いですが。 | ||||||||||||
|
投稿日時: 2007-05-20 12:10
よっしーさん、ご指摘ありがとうございます。
10万件繰り返し→1回コミットでしたか。。。 それはこのスレッドを立てる前に実現できていました。 そもそも ・1レコード読み取り→SQL→コミットを10万回繰り返す ・1レコード読み取り→SQLを10万回繰り返し、最後に一発コミット 上記の2点はスレッドを立てる前に実装でき、検証もできていました。 しかし性能を向上させるためには、コミット間隔を50〜100件にするのが 自明の理だと思っていましたので、その実装方法がわからず、スレッドを たてさせていただきました。 よろしくお願い致します。 | ||||||||||||
|
投稿日時: 2007-05-21 11:25
そこは単純に変数の2重定義ですよね? #そういうエラー内容になっていると思いますが。。。
100件単位での登録で、エラーになった部分のデータを破棄するとか、ちょっと理解出来ませんが。 正常なデータも捨ててしまうのですか?
コミット実行には結構コストがかかりますよ。 つまり、コミット回数が増えれば増えるだけ、コストが増大します。 [追記] 高速で登録を行いたいと言うのであれば、SQL*Loaderを使う手もありますが。 [ メッセージ編集済み 編集者: マーサ 編集日時 2007-05-21 11:41 ] | ||||||||||||
|
投稿日時: 2007-05-21 12:36
これもし500件の時はどうなるんですか? 1〜200は同じとして、201〜300が出力されないまではわかります。 ではその後は? 301〜は処理するんですか? それともエラー出た時点で処理が止まって、301〜500も全て出力しないんですか? どういったデータなのかわかりませんが、一つエラーがあっただけで 他の正常に登録できるであろうデータを切り捨てるというのはどうなんでしょう。 100件単位にすれば、100件のうち1件でもエラーあれば最低99件が無駄に。 1000件単位にすれば999件が無駄に。 10件単位だと9件が無駄に。 分ける単位によって無駄が増減するのも仕様としてどうなのかなと。 | ||||||||||||
|
投稿日時: 2007-05-21 13:37
その自明の部分を掘り下げてみたら?と言いたいのだと思いますよ。 数百件おきにコミットを行うのは速度上の問題というよりは、HDD容量の問題で行われていた実装です。100万レコードを一度にコミットするためには100万レコードを格納するための大きなロールバックセグメントが必要になります。HDDが高価な時代、大容量のロールバックセグメントを用意するなんて出来なかったんですよ。 HDDが安価な現代においては、巨大なロールバックセグメントを用意するという選択もあるはずです。コミットを一度ですませば「トランザクション分離」とか「ロールバック処理」、「読み取り一貫性」などの恩恵も受けられます。 | ||||||||||||
|
投稿日時: 2007-05-21 14:00
もしかして、要件的にトランザクション管理がいらないのでは?
BeginTransactionしなければ良いのでは? |