- - PR -
SQL?
1|2|3
次のページへ»
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-10-09 10:59
お世話になっております。 ケイゴでございます。
今、SQL文を5000回発行して、25万レコードを取得しているのですが、 4分もかかってしまっています。 なにかよい方法はない物でしょうか。 現段階のソースは For j = Sepk To range '==========00001〜50000 '&&&&&&&&&&&&&&&&&&&&&&& 1行目の情報を取得し、表示する workRow = workTable.NewRow() workRow(oridata(0)) = comb(j - 1) ' 1列目---品名コード '以下のSQL文でグリッド1行分(PK1つ分)の情報全てを持ってくる。 strSQL = "select * from " & tblname0 & " where PK = '" & comb(j - 1) & "' and KBN_NM = '" & strBtnm & "' order by No" OleDbDataAdapter1.SelectCommand.CommandText = strSQL DataSet31.Clear() OleDbDataAdapter1.Fill(DataSet31, "Emp") 'コマンド実行 i = 1 For Each drora In DataSet31.Tables("Emp").Rows oridata5(i) = drora(2).ToString() '----------項目キー oridata3(i) = drora(3).ToString() '----------項目区分 If oridata3(i) = "1" Then oridata4(i) = drora(4).ToString() '----------項目c ElseIf oridata3(i) = "2" Then oridata4(i) = drora(5).ToString() '----------項目n End If workRow(oridata(i)) = oridata4(i) i = i + 1 Next DataSet31.Clear() workTable.Rows.Add(workRow) Next です。 | ||||||||
|
投稿日時: 2003-10-09 11:28
SQL文を5000回発行って・・・。 もしSQL文を5000回発行する以外に方法がないなら、 ストアドプロシジャーを使用してみてはいかがでしょうか? ただし、すべてのDBでストアドプロシジャーが使用できるわけではありません。 | ||||||||
|
投稿日時: 2003-10-09 11:41
こんにちは。
以下、DBがOracleだった場合の投稿ですので、違う場合は読み飛ばして下さい。 ------------------------------------------------------------------ strSQL = "select * from " & tblname0 & " where PK = '" & comb(j - 1) & "' and KBN_NM = '" & strBtnm & "' order by No" のSQL文ですが、「*」を列名指定することによりOracleの内部置換が減少すると思います。 実際に全ての行が必要で無ければ、列名は指定してしまう方が良いでしょう。 また、SQL文に関してですが、Oracleは内部で 「小文字を大文字に置換する処理」も入っているので (バージョンにも依存するかもしれませんが。) 大文字で記述される癖を付けられても良いかと思います。 ※おそらくこちらは影響を意識するレベルでは無いかと思いますが。 ------------------------------------------------------------------------ DB (or SQL) でのチューニングが完了している状態ならば、 プログラムの最適化、変更を行うべきであると思いますが 完了していない場合はまずDB (or SQL) を当たってみるのはどうでしょうか。 | ||||||||
|
投稿日時: 2003-10-09 11:56
こんにちは、皆様のご意見にプラスして・・・。
> strSQL = "select * from " & tblname0 & " where PK = '" & comb(j - 1)& "' > and KBN_NM = '" & strBtnm & "' order by No" このテーブルのPKやKBN_NMってchar型ですか?? int型などでしたらシングルコーテーションは要らないと思います。 間違っていたらごめんなさい。 ※Crimeさんもおっしゃっているように先ずはDBのチューニングが先かと思います。 | ||||||||
|
投稿日時: 2003-10-09 12:01
ども、ほむらです。
ケイゴ氏へ
テーブル構造とかデータの特徴がわからないので SQLや処理内容に関してなんともいえませんけど where PK = '" & comb(j - 1)の部分だけは IN句で書き直せそうな感じもしますね。。 いくつまで列挙できるのか調査したこと無いですけど(byte制限もあるでしょうし)、 SQLの実行回数を減らすことは可能だと思いますよ。 # 追加 ・・・ ところでINDEXはPKとKBN_NMにはってありますか? Crime氏へ
oracleでは、こんな変換までしていたのですか〜 習慣的に小文字で書くようにしていたのですけど 大文字で書いたほうが良かったんですね。 #追加を追加 [ メッセージ編集済み 編集者: ほむら 編集日時 2003-10-09 12:12 ] | ||||||||
|
投稿日時: 2003-10-09 12:06
こんにちは。
率直な感想…なにがしたいんか、ようわからん。 {workRow(oridata(i)) =}って、oridata(i)の内容は? いろいろ代入しているけれど、結局いるのはoridata4だけ? そもそも、配列に格納する必要があるの? 1.DataSet31.Clearを2回発行しているが、どちらかは不要では? 2.DataAdapter.FillメソッドはDataTableも受け付けるので、それでもいいのでは? 3.プレースホルダを利用すればSQL文の解析がなくなる分、速くなる 4.テーブルに適切にINDEXが張ってあれば、検索は速くなる (Oacleの実行計画を参照して、チューニングする) 5.項目cとnは、Oracle側でDECODE関数を使えば判別不要 6.SELECTする項目は、全て列挙する方が高速になる (Oracle内部で展開処理をする時間が稼げる) 7.oridata?配列は、十分に領域確保されているか (自動確保より事前確保の方が高速) ざっと見で、こんなところ。提示されているものが全てではないでしょうが、そうであれば、まずはどこでどれくらい時間がかかっているのか、実測して確実に把握する必要があります。 | ||||||||
|
投稿日時: 2003-10-09 12:27
とすることにより、1回のSQL発行で済ませることが可能です。ただし、多少ロジックを工夫する必要はありますが。 この方法で必ず高速化が図れるとは言えませんが、ご参考までに。 | ||||||||
|
投稿日時: 2003-10-09 13:01
「25万件のレコードを使って何をしようとしているのか」を説明し,
その方法論を相談に乗って頂くのが「高速化」につながるのではないかと 思います。チューニングはその後かと。 「25万種ある商品の月別売上一覧表をブラウザ上でみたい」とか, 「25万種ある商品マスタのメンテナンスをブラウザから行いたい」とか, やりたい事はいろいろ考えられます。 それが分かってから, 「じゃぁ,DB側に商品ごとに集計したビューでも作るか」とか 「メンテナンスしたい項目を指定してから,必要な情報だけブラウザに表示させるか」とか 考えた方がよいと思います。 以前,似たような回答をJittaさんがしています。 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=6652&forum=7&4 |
1|2|3
次のページへ»