- PR -

SQL?

投稿者投稿内容
ケイゴ
会議室デビュー日: 2003/10/01
投稿数: 15
投稿日時: 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
です。
taku
ぬし
会議室デビュー日: 2002/11/12
投稿数: 918
お住まい・勤務地: 墨田区→中野区
投稿日時: 2003-10-09 11:28
引用:

ケイゴさんの書き込み (2003-10-09 10:59) より:
お世話になっております。 ケイゴでございます。
今、SQL文を5000回発行して、25万レコードを取得しているのですが、
4分もかかってしまっています。
なにかよい方法はない物でしょうか。


 SQL文を5000回発行って・・・。
もしSQL文を5000回発行する以外に方法がないなら、
ストアドプロシジャーを使用してみてはいかがでしょうか?
ただし、すべてのDBでストアドプロシジャーが使用できるわけではありません。
Crime
常連さん
会議室デビュー日: 2002/08/26
投稿数: 34
お住まい・勤務地: Japan
投稿日時: 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) を当たってみるのはどうでしょうか。
momotaro
会議室デビュー日: 2003/07/23
投稿数: 14
投稿日時: 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/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-10-09 12:01
ども、ほむらです。
ケイゴ氏へ
引用:

strSQL = "select * from " & tblname0 & " where PK = '" & comb(j - 1) & "' and KBN_NM = '" & strBtnm & "' order by No"


テーブル構造とかデータの特徴がわからないので
SQLや処理内容に関してなんともいえませんけど
where PK = '" & comb(j - 1)の部分だけは
IN句で書き直せそうな感じもしますね。。
いくつまで列挙できるのか調査したこと無いですけど(byte制限もあるでしょうし)、
SQLの実行回数を減らすことは可能だと思いますよ。

# 追加 ・・・ ところでINDEXはPKとKBN_NMにはってありますか?

Crime氏へ
引用:

また、SQL文に関してですが、Oracleは内部で
「小文字を大文字に置換する処理」も入っているので
(バージョンにも依存するかもしれませんが。)
大文字で記述される癖を付けられても良いかと思います。
※おそらくこちらは影響を意識するレベルでは無いかと思いますが。


oracleでは、こんな変換までしていたのですか〜
習慣的に小文字で書くようにしていたのですけど
大文字で書いたほうが良かったんですね。

#追加を追加

[ メッセージ編集済み 編集者: ほむら 編集日時 2003-10-09 12:12 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 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/08/08
投稿数: 317
お住まい・勤務地: お花畑
投稿日時: 2003-10-09 12:27
コード:
strSQL = "select * from " & tblname0 & " where KBN_NM = '" & strBtnm & "' order by PK, No" 


とすることにより、1回のSQL発行で済ませることが可能です。ただし、多少ロジックを工夫する必要はありますが。
この方法で必ず高速化が図れるとは言えませんが、ご参考までに。
聖人@SKB
ベテラン
会議室デビュー日: 2003/03/26
投稿数: 58
お住まい・勤務地: 横浜(MM21)勤務の筈だがいつも顧客先常駐
投稿日時: 2003-10-09 13:01
「25万件のレコードを使って何をしようとしているのか」を説明し,
その方法論を相談に乗って頂くのが「高速化」につながるのではないかと
思います。チューニングはその後かと。

「25万種ある商品の月別売上一覧表をブラウザ上でみたい」とか,
「25万種ある商品マスタのメンテナンスをブラウザから行いたい」とか,
やりたい事はいろいろ考えられます。
それが分かってから,
「じゃぁ,DB側に商品ごとに集計したビューでも作るか」とか
「メンテナンスしたい項目を指定してから,必要な情報だけブラウザに表示させるか」とか
考えた方がよいと思います。

以前,似たような回答をJittaさんがしています。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=6652&forum=7&4

スキルアップ/キャリアアップ(JOB@IT)