DOBON.NET DOBON.NETプログラミング掲示板過去ログ

SQL SELECT文で2つのテーブルから取得すると遅い

環境/言語:[WindowsXP]
分類:[.NET]

どなたか、SQLについて詳しい方がいらっしゃいましたらご教授してくださりませんでしょうか。
環境は、WindowsXP + VB.NET です。SQLについては初心者です。

以下のような2つのテーブルを持つMDBファイルから、2つのテーブルからまとめて1回で
siiresaki と seihin の2つを指定して日付順に nyuuko と furyou を並べてデータを取得しようと思い、
いろいろ調べて素人なりに、SELECT文を書いて何とか取得できるようになったのですがみたのですが、
ものすごく遅です。(10秒以上)
もし、効率のよいSQL文の書き方がありましたら教えて頂きたいのですが。

それとも、このようなケースでは1つのテーブルから、Table1とTable2から1回づつ2回に分けて取得して
からVBのコードでつなぎ合わせるのが正道なのでしょうか?この方法だと1秒もかからないです。

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

[MDBのデータベース]
Table1(仕入)
hiduke    |siiresaki |seihin |nyuuko | tanka ...
---------------------------------------
04/01/05  | 001   | A01  | 100
04/01/05  | 001   | B01  | 150
04/01/05  | 002   | A01  | 200
04/01/07  | 001   | A01  | 330
04/01/07  | 002   | B01  | 250
04/01/09  | 001   | A01  | 120

Table2(不良品)
hiduke    |siiresaki |seihin |furyou|
-----------------------------------------------
04/01/05  | 001   | A01  | 5
04/01/05  | 001   | B01  | 12
04/01/05  | 002   | A01  | 18
04/01/07  | 001   | A01  | 21
04/01/07  | 002   | B01  | 10
04/01/09  | 001   | A01  | 6

[SQL問い合わせ結果]
siiresaki =001 で seihin = A01
hiduke    |nyuuko |furyou |
----------------------------
04/01/05  | 100   | 5
04/01/05  | 330   | 18
04/01/05  | 120   | 6

[私の書いたSQL文]
SQLSTR = "SELECT T1.hiduke, T1.nyuuko, T2.furyou FROM 仕入 T1 , 不良品 T2 "
SQLSTR += "WHERE T1.hiduke = T2.hiduke AND T1.siiresaki = T2.siiresaki AND T1.seihin = T2.seihin "
SQLSTR += "AND T1.siiresaki = 100 AND T1.seihin = 'A01' "
SQLSTR += "ORDER BY T1.hiduke"
[質問文の補足]
今、Accessでテーブルのデザインをみたところ、どちらのテーブルも
hiduke、siiresaki、seihin のフィールドに鍵のマークが表示されていました。
■No3163に返信(ポンさんの記事)
> どなたか、SQLについて詳しい方がいらっしゃいましたらご教授してくださりませんでしょうか。
> 環境は、WindowsXP + VB.NET です。SQLについては初心者です。
>
> 以下のような2つのテーブルを持つMDBファイルから、2つのテーブルからまとめて1回で
> siiresaki と seihin の2つを指定して日付順に nyuuko と furyou を並べてデータを取得しようと思い、
> いろいろ調べて素人なりに、SELECT文を書いて何とか取得できるようになったのですがみたのですが、
> ものすごく遅です。(10秒以上)
> もし、効率のよいSQL文の書き方がありましたら教えて頂きたいのですが。
>
> それとも、このようなケースでは1つのテーブルから、Table1とTable2から1回づつ2回に分けて取得して
> からVBのコードでつなぎ合わせるのが正道なのでしょうか?この方法だと1秒もかからないです。
>
> 何卒よろしくお願いいたします。
>
> [MDBのデータベース]
> Table1(仕入)
> hiduke    |siiresaki |seihin |nyuuko | tanka ...
> ---------------------------------------
> 04/01/05  | 001   | A01  | 100
> 04/01/05  | 001   | B01  | 150
> 04/01/05  | 002   | A01  | 200
> 04/01/07  | 001   | A01  | 330
> 04/01/07  | 002   | B01  | 250
> 04/01/09  | 001   | A01  | 120
>
> Table2(不良品)
> hiduke    |siiresaki |seihin |furyou|
> -----------------------------------------------
> 04/01/05  | 001   | A01  | 5
> 04/01/05  | 001   | B01  | 12
> 04/01/05  | 002   | A01  | 18
> 04/01/07  | 001   | A01  | 21
> 04/01/07  | 002   | B01  | 10
> 04/01/09  | 001   | A01  | 6
>
> [SQL問い合わせ結果]
> siiresaki =001 で seihin = A01
> hiduke    |nyuuko |furyou |
> ----------------------------
> 04/01/05  | 100   | 5
> 04/01/05  | 330   | 18
> 04/01/05  | 120   | 6
>
> [私の書いたSQL文]
> SQLSTR = "SELECT T1.hiduke, T1.nyuuko, T2.furyou FROM 仕入 T1 , 不良品 T2 "
> SQLSTR += "WHERE T1.hiduke = T2.hiduke AND T1.siiresaki = T2.siiresaki AND T1.seihin = T2.seihin "
> SQLSTR += "AND T1.siiresaki = 100 AND T1.seihin = 'A01' "
> SQLSTR += "ORDER BY T1.hiduke"
>

どれだけ高速化できるか判りませんが…。
結合条件をWHERE句に記述するのではなく、INNER JOIN句で宣言するようにすればいいかと思います。

あと、くだらないツッコミですが[SQL問い合わせ結果]が間違っていますね。
恐らくコピーペースト後の修正忘れだと思いますけど。
■No3167に返信(琴さんの記事)
> ■No3163に返信(ポンさんの記事)
>
>
> どれだけ高速化できるか判りませんが…。
> 結合条件をWHERE句に記述するのではなく、INNER JOIN句で宣言するようにすればいいかと思います。

>SQLについては初心者です。

SQL文の書き方が知りたいということなので

ちなみにINNER JOINだと

SQLSTR = "SELECT T1.hiduke, T1.nyuuko, T2.furyou"
SQLSTR += " FROM 仕入 T1"
SQLSTR += " INNER JOIN 不良品 T2"
SQLSTR += " ON T1.hiduke = T2.hiduke "
SQLSTR += " AND T1.siiresaki = T2.siiresaki"
SQLSTR += " AND T1.seihin = T2.seihin "
SQLSTR += " WHERE T1.siiresaki = 100 AND T1.seihin = 'A01'"
SQLSTR += " ORDER BY T1.hiduke"

このようになります。
Tom'sさん、琴さん、アドバイスありがとうございます。
今、Accessでデータベースの最適化を行ったのですが、
これが原因がどうか分かりませんが、自分の書いたコード
でも、時間がかからずほぼ一瞬で実行できるようになりました。

Tom'sさんのご指摘の通り、最初に線の部分ガずれてるのでコピペ
してなおしてたら[SQL問い合わせ結果]が間違っていました。
申し訳ありません。

琴さん、ご親切にコードを教えて頂きありがとうございます。
私は簡単なSELECT文しか書いたことがなかったので、大変助かりました。

今回、Accessでデータベースの最適化を行ったせいか、
INNER JOIN句を使った場合の速度の比較があまり感じられなかったのですが
もう一度、最適化する前のファイルで試してみたいと思います。
■No3167に返信(琴さんの記事)
> どれだけ高速化できるか判りませんが…。
> 結合条件をWHERE句に記述するのではなく、INNER JOIN句で宣言するようにすればいいかと思います。

ポンさんの書かれたSQL文は内部結合(INNER JOIN)ですが、
SQLの標準規格のSQL92での記述方式であるINNER JOIN句を使った方が、
mdbでは処理速度が速くなるでしょうか?
(あるいはmdbに限らずINNER JOIN句に対応しているDBMSの場合の一般論として)

これは初めて聞きました。
この情報源になっているURL等あればお教えください。

■No3183に返信(ポンさんの記事)
> Tom'sさん、琴さん、アドバイスありがとうございます。
> 今、Accessでデータベースの最適化を行ったのですが、
> これが原因がどうか分かりませんが、自分の書いたコード
> でも、時間がかからずほぼ一瞬で実行できるようになりました。

ポンさんの書かれたSQLはごく単純なSQLで、しかも結合条件が主キーだけなので、
もうこれ以上は速くしようがないと思います。
(INNER JOIN句を使った記述にした場合のことは知りませんが、それを除けば)

アクセスではUpdate/Deleteを繰り返すとmdbファイルがどんどん肥大していって、
検索の性能もぐんぐん落ちていきますので、頻繁に最適化することをお勧めします。
よねKENさん、情報ありがとうございます。
今、最適化する前のファイルで試ししみたのですが、INNER JOIN句を使うより
最初に私が書いたSQLのほうが早かったです。
自信がなかったのですが、よねKENさんにご意見を頂き確信できました。

最初にTom'sさんに教えて頂いたSQLで検索すると、30秒くらい時間がかかり
2回目からは、一瞬で検索が終わるようになりました。
私が最初に書いたSQLでは、何回やっても同じように時間がかかったので
自分の書いたコードに問題があるのか、SQLはもともとこうなのか解らな
かったので質問させて頂いたのですが、どうも私の環境に何か問題があっ
たみたいです。ご迷惑をおかけして申し訳ありませんでした。

Tom'sさん、琴さん、よねKENさん、アドバイスありがとうございました。
今後ともよろしくお願いいたします。 m(_ _)m
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板