- - PR -
JOIN句
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-05-14 15:24
こんにちわ。
既存のSQLの応答時間が遅いので、修正した所時間短縮されていなくて困っています。 JOINを使用しているのですが。。 UNIONを使用した方がいいのでしょうか? <修正前> SELECT PPL.使用数量1, PPL.使用数量2, PPL.使用数量3, PPL.使用数量4, PPL.使用数量5, PPL.使用数量6, PPL.使用数量7, PPL.使用数量8, PPL.使用数量9, PPL.使用数量10, PPL.使用数量11, PPL.使用数量12, (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量1 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量2 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量3 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量4 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量5 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量6 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量7 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量8 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量9 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量10 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量11 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量12 END), HNM.品名, STJ.規格1, STJ.規格2, STJ.規格3, STJ.規格4, STJ.規格5, SEM.枝番名称, PPL.使用製品群在庫種別 AS 在庫種別, STJ.材料基準単価, KBH.区分名称, STJ.フラフリターン率, ((CASE WHEN STJ.仕入区分 = '1' THEN '1' ELSE '0' END) || HNM.資材大分類コード || HNM.資材中分類コード || HNM.資材小分類コード) AS 品名分類, STJ.グレード, STJ.色番 FROM ( BCFPPLD PPL LEFT OUTER JOIN BCMKBHD KBH ON PPL.削除区分 = '0' AND PPL.会社コード = '01' AND PPL.年度 = '2007' AND PPL.部署コード = '3240' AND KBH.削除区分 = '0' AND KBH.会社コード = PPL.会社コード AND KBH.項目コード = '0070' ) , BCMSCMD TJM, BCMMTRD STJ, BCMHNMD HNM,BCMSGMD SGM,BCMSEMD SEM WHERE PPL.削除区分 = '0' AND PPL.会社コード = '01' AND PPL.年度 = '2007' AND PPL.部署コード = '3240' AND TJM.削除区分 = '0' AND TJM.会社コード = '01' AND TJM.製造工場コード = (PPL.使用工場取引先コード || PPL.使用工場取引先口座コード) AND TJM.製品群コード = PPL.使用製品群コード AND TJM.製品群枝番 = PPL.使用製品群枝番 AND TJM.適用日付 <= '20070321' AND TJM.有効日付 >= '20070321' AND STJ.削除区分 = '0' AND STJ.会社コード = '01' AND STJ.製造工場コード = (PPL.使用工場取引先コード || PPL.使用工場取引先口座コード) AND STJ.製品群コード = PPL.使用製品群コード AND STJ.製品群枝番 = PPL.使用製品群枝番 AND STJ.適用日付 = TJM.適用日付 AND STJ.品名コード = PPL.製品群品名使用資材コード AND HNM.品名コード = PPL.製品群品名使用資材コード AND HNM.品名コード枝番 = '0' AND HNM.削除区分 = '0' AND SGM.会社コード = '01' AND SGM.製品群コード = PPL.使用製品群コード AND SGM.適用日付 <= '20070321' AND SGM.有効日付 >= '20070321' AND SGM.削除区分 = '0' AND SEM.会社コード = '01' AND SEM.製品群コード = PPL.使用製品群コード AND SEM.適用日付 = SGM.適用日付 AND SEM.製品群枝番 = PPL.使用製品群枝番 AND SEM.削除区分 = '0' AND KBH.区分コード = STJ.材料基準単価単位コード ORDER BY 品名分類,PPL.製品群品名使用資材コード, STJ.グレード,STJ.色番,STJ.規格1,STJ.規格2,STJ.規格3,STJ.規格4,STJ.規格5, PPL.使用製品群コード,PPL.使用製品群枝番,在庫種別 <修正後> SELECT DISTINCT 使用数量1, 使用数量2, 使用数量3, 使用数量4, 使用数量5, 使用数量6, 使用数量7, 使用数量8, 使用数量9, 使用数量10, 使用数量11, 使用数量12, (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量1 END), (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量2 END), (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量3 END), (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量4 END), (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量5 END), (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量6 END), (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量7 END), (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量8 END), (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量9 END), (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量10 END), (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量11 END), (CASE WHEN 区分コード = '05' THEN 0 ELSE 使用重量12 END), 品名 FROM BCFPPLD PPL LEFT JOIN ( SELECT 区分コード, 区分名称 FROM BCMKBHD KBH WHERE 会社コード='01' AND 削除区分='0' AND 項目コード = '0070' ) A ON PPL.会社コード = 会社コード LEFT JOIN ( SELECT 品名,品名コード,品名コード枝番, 資材大分類コード,資材中分類コード, 資材小分類コード FROM BCMHNMD HNM WHERE 品名コード枝番 = '0' AND 削除区分='0') B ON PPL.製品群品名使用資材コード = 品名コード LEFT JOIN ( SELECT 製品群コード, 適用日付 FROM BCMSGMD SGM WHERE 会社コード = '01' AND 削除区分 = '0' ) C ON C.製品群コード = PPL.使用製品群コード LEFT JOIN ( SELECT 製品群コード, 適用日付, 製品群枝番, 枝番名称 FROM BCMSEMD SEM WHERE 会社コード = '01' AND 削除区分='0' ) D ON D.製品群コード = PPL.使用製品群コード WHERE PPL.削除区分 = '0' AND PPL.会社コード = '01' AND PPL.年度 = '2007' AND PPL.部署コード = '3240' まだ、途中なんですが、すべてのテーブルを結合した時点であまり応答時間が変わりませんでした。 どなたか教えていただけないでしょうか。 | ||||||||
|
投稿日時: 2007-05-14 16:13
msoです。
長いので全部みていませんが、UNIONにしてもあまり変わらないと思います。 INDEXとかは適切に使われていますか? ご確認ください。 | ||||||||
|
投稿日時: 2007-05-14 16:23
どんなRDBを使うかで全然チューニング方法違いますが、
その件について明記すべきでしょう。 でも、これだけ大きいSQLを貼り付けたところで読む気がしませんね。 まずは、お使いのRDBに実行プランを参照する方法があれば、それを使いましょう。 SQLのどの部分にコストが沢山かかっているかが分かります。 | ||||||||
|
投稿日時: 2007-05-14 16:56
こんにちわ
素早い返信ありがとうございます。 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− MSOさんへ −−−−−−−−−−−−−−−−−−−−− >INDEXとかは適切に使われていますか? −−−−−−−−−−−−−−−−−−−−− 修正前のSQLをもとにして、テーブルの構成を参照し、書いたのですが。 もう一度考え直します。 ありがとうございます。 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−− ぬしさんへ もう一度、どの部分にコストがかかっているか検証し、 修正に取り組みます。 ありがとうございます。 環境は、OSがXP DBソフトが富士通のsymfoware です。 明記していなくてすいません。 | ||||||||
|
投稿日時: 2007-05-14 19:18
以前ORACLEでですが、WHEREの条件をFROM句にもってきたら遅い検索が
高速になったことがありました。 Symfoware でどうなるかまったくわかりませんが...
| ||||||||
|
投稿日時: 2007-05-15 09:04
温州蜜柑さんへ
返事おそくなりすいません。 dual句を使用するということは気がつきませんでした。 一行一列のダミーテーブルとして使用の場合は有効なんですかね。 symfoで使用できるとは知りませんでした。 上記を参考にし、もう一度組みなおして作業します。 ありがとうございました。 | ||||||||
|
投稿日時: 2007-05-15 10:59
#質問の回答ではないです。
symfoware使ったこと無いので違ってたらすいません。 修正前と修正後で結合条件が変わっている気がするんですが大丈夫でしょうか? (上は内部結合、下は外部結合) 直すとこうなるのかな?(動作確認はしていないです) SELECT PPL.使用数量1, PPL.使用数量2, PPL.使用数量3, PPL.使用数量4, PPL.使用数量5, PPL.使用数量6, PPL.使用数量7, PPL.使用数量8, PPL.使用数量9, PPL.使用数量10, PPL.使用数量11, PPL.使用数量12, (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量1 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量2 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量3 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量4 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量5 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量6 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量7 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量8 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量9 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量10 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量11 END), (CASE WHEN KBH.区分コード = '05' THEN 0 ELSE PPL.使用重量12 END), HNM.品名, STJ.規格1, STJ.規格2, STJ.規格3, STJ.規格4, STJ.規格5, SEM.枝番名称, PPL.使用製品群在庫種別 AS 在庫種別, STJ.材料基準単価, KBH.区分名称, STJ.フラフリターン率, ((CASE WHEN STJ.仕入区分 = '1' THEN '1' ELSE '0' END) || HNM.資材大分類コード || HNM.資材中分類コード || HNM.資材小分類コード) AS 品名分類, STJ.グレード, STJ.色番 FROM ( BCFPPLD PPL LEFT OUTER JOIN BCMKBHD KBH ON KBH.会社コード = PPL.会社コード AND KBH.区分コード = STJ.材料基準単価単位コード ) inner join BCMSCMD TJM on TJM.製造工場コード = (PPL.使用工場取引先コード || PPL.使用工場取引先口座コード) AND TJM.製品群コード = PPL.使用製品群コード AND TJM.製品群枝番 = PPL.使用製品群枝番 inner join BCMMTRD STJ on STJ.製造工場コード = (PPL.使用工場取引先コード || PPL.使用工場取引先口座コード) AND STJ.製品群コード = PPL.使用製品群コード AND STJ.製品群枝番 = PPL.使用製品群枝番 AND STJ.適用日付 = TJM.適用日付 AND STJ.品名コード = PPL.製品群品名使用資材コード inner join BCMHNMD HNM on HNM.品名コード = PPL.製品群品名使用資材コード inner join BCMSGMD SGM on SGM.製品群コード = PPL.使用製品群コード inner join BCMSEMD SEM on SEM.製品群コード = PPL.使用製品群コード AND SEM.適用日付 = SGM.適用日付 AND SEM.製品群枝番 = PPL.使用製品群枝番 WHERE PPL.削除区分 = '0' AND PPL.会社コード = '01' AND PPL.年度 = '2007' AND PPL.部署コード = '3240' AND KBH.削除区分 = '0' AND KBH.項目コード = '0070' PPL.削除区分 = '0' AND TJM.削除区分 = '0' AND TJM.会社コード = '01' AND TJM.適用日付 <= '20070321' AND TJM.有効日付 >= '20070321' AND STJ.削除区分 = '0' AND STJ.会社コード = '01' AND HNM.品名コード枝番 = '0' AND HNM.削除区分 = '0' AND SGM.会社コード = '01' AND SGM.適用日付 <= '20070321' AND SGM.有効日付 >= '20070321' AND SGM.削除区分 = '0' AND SEM.会社コード = '01' AND SEM.削除区分 = '0' ORDER BY 品名分類,PPL.製品群品名使用資材コード, STJ.グレード,STJ.色番,STJ.規格1,STJ.規格2,STJ.規格3,STJ.規格4,STJ.規格5, PPL.使用製品群コード,PPL.使用製品群枝番,在庫種別 | ||||||||
|
投稿日時: 2007-05-15 13:37
ちょっとひらめきました。 各種マスタで「 削除区分 = '0' 」という条件があるのがガンなのではないでしょうか? 「case when ... 」を使用して以下のようにしたらいかがでしょう? ※ eterniaさんが指摘しているように、「修正前」と「修正後」のクエリが ちがっていますね? とりあえず、「修正後」のクエリを私なりに改造してみました。
|