🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

1439閲覧

SQL 発行の組み方次第のスピードについて

saya24

総合スコア246

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

1クリップ

投稿2021/01/15 01:16

編集2021/01/15 11:00

SQL

1SELECT A.代理店コード, F.代理店名, A.お客様コード, G.お客様名 2FROM トランザクション A 3LEFT OUTER JOIN NDSS.[dbo].[代理店マスタ] F ON F.代理店コード=A.代理店コード 4LEFT OUTER JOIN NDSS.[dbo].[お客様マスタ] G ON G.お客様コード=A.お客様コード 5WHERE (F.代理店コード IS NOT NULL AND F.削除フラグ<>'D') AND (G.お客様コード IS NOT NULL AND G.削除フラグ<>'D')

Aをベースに、関連づけられた参照マスタ2種類がある発行ですが
・参照マスタ側は 必ずしもAに関連づけられた レコードがあるとは 限らない
・どちらかの参照マスタで、削除が宣言されていたら、発行結果=行を得ない
要件を達成したく、現況上記のようなSQL文になっています。
しかし 結構スピードが遅く感じています。

###質問

SQL

1SELECT X.代理店コード, X.代理店名, X.お客様コード, X.お客様名 FROM 2(SELECT A.代理店コード, F.代理店名, ■F.削除フラグ AS 削除フラグF, A.お客様コード, G.お客様名, ■G.削除フラグ AS 削除フラグG 3FROM トランザクション A 4LEFT OUTER JOIN NDSS.[dbo].[代理店マスタ] F ON F.代理店コード=A.代理店コード 5LEFT OUTER JOIN NDSS.[dbo].[お客様マスタ] G ON G.お客様コード=A.お客様コード)) X 6WHERE (X.削除フラグF<>'D') AND (X.削除フラグG<>'D')

上記のようにSQL文を組みなおすことで スピード向上は 期待できるのでしょうか? <==== スピード向上が果たされるとしても
削除フラグを含めるためだけに 元のSQL文をまるっと 副問い合わせにするような手立てが 恥ずかしい解決策でないか
不安に思いましたので 本問い合わせに至りました 

ご見解いただけたら 幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/01/15 01:18

SQLもDBの種類によって機能や性能に差があります。 また、テーブル定義にも影響します。 想定されている環境、テーブル定義 提示してください。 パフォーマンス向上を目指す場合、総合的な観点で対応する必要があり、 可能なら定義から見直した方が良いと思います。
gentaro

2021/01/15 01:48

> 上記のようにSQL文を組みなおすことで スピード向上は 期待できるのでしょうか? 自分で試してみようと思わず質問しているのであればガイドラインに反してます。 https://teratail.com/help/question-tips#questionTips1-2 「投稿前に検索し、できるところまで自分でやってみましょう」
kaina

2021/01/15 01:49

DBの種類が何か分かりませんが、直接SQLを実行して試してみれば直ぐ分かるので まずご自分で試して下さい。
saya24

2021/01/15 06:08

ひとまず MicrosoftのSQLServerです。 スピード以前 非常識なことを対応方針か否か 知りたくて 問い合わせたところが大きいです。
m.ts10806

2021/01/15 06:22

質問本文調整してください。 リファクタリングやパフォーマンスチューニングは前提として「以前と同じ動作結果を得られること」です。 「スピードが遅い」だけでは感覚だけでしかないので、実行計画や速度を数値ではかったうえで「何を目指すか」を決めて(ゴールのこと)やっていかないと、やろうと思えばどこまでもできてしまう(つまり「ベスト」などない)ものです。 許容範囲やラインを決めてください。
saya24

2021/01/15 06:49

m.ts10806さん、ご見解ありがとうございます。 自分が作成したSQL文を 第3者が確認された際に 非常識と思われるといやだなぁと思いまして、スピードが速かったとしても 自分の案は 採用すべきでないな、ほかに案はあるかな、と思ったのです。
m.ts10806

2021/01/15 06:51

「想定通りに動く」なら非常識も何もないのでは。 結局プログラムは書いたとおりにしか動かないわけですし。
kaina

2021/01/15 12:27

>上記のようにSQL文を組みなおすことで スピード向上は 期待できるのでしょうか?  ><==== スピード向上が果たされるとしても >削除フラグを含めるためだけに 元のSQL文をまるっと 副問い合わせにするような手立てが  >恥ずかしい解決策でないか >不安に思いましたので 本問い合わせに至りました  おかしな文章ですね、まず組み立て直したSQLを実行してスピード向上していることを確認した後に その方法が妥当かどうかを気にするべきではありませんか??? もし逆にスピードが遅くなっていたらそれは間違った方法で、別の方法を検討する必要があるわけですよね? 言い訳ばかりするのではなく、まず自分で手を動かしましょう。
saya24

2021/01/15 12:47

いま案の方法でやりましたが 以前より 遅かったです。 ともあれ試すべきだ、という見解が多く寄せられ 皆さんのお時間をいただいてしまい申し訳ありません。 本来どういった発行分がベストなのかが わからないのが もどかしいです。
saya24

2021/01/15 14:25

kainaさん 有用な情報をありがとうございます、勉強させて頂きます。 本件クローズとします。
m.ts10806

2021/01/16 00:28

ここまで具体的な数字の話なし。 ------------------------------------------ 「スピードが遅い」だけでは感覚だけでしかないので、実行計画や速度を数値ではかったうえで「何を目指すか」を決めて(ゴールのこと)やっていかないと、やろうと思えばどこまでもできてしまう(つまり「ベスト」などない)ものです。 許容範囲やラインを決めてください。
guest

回答2

0

ベストアンサー

F.代理店コード IS NOT NULL
G.お客様コード IS NOT NULL
って記述するなら外部結合にする意味はないでしょう。
2つの LEFT OUTER JOIN は INNER JOIN で記述するべきでは?

質問に、CREATE TABLE, CREATE INDEX, 実行計画を追記できた方が適切なコメントが付き易いかと。
[SQL Server]タグも追加しては?

投稿2021/01/15 07:01

Orlofsky

総合スコア16417

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2021/01/15 11:12 編集

いつもお世話になっております。 >2つの LEFT OUTER JOIN は INNER JOIN で記述するべきでは? 内部結合にしたら 2つのテーブルに存在しないレコードが 行結果を得られなくなってしまうのではないでしょうか? いづれかのマスタで あえて削除が宣言されていれば 当該行の結果を得たくないわけです。 あるとは 限らないマスタなので、基本それらマスタの存在関係なく メインのトランザクション Aから行結果を表示する。 だけれど、いづれかのマスタのほうで 削除と宣言されていれば Aからも行結果を出さない というのが理想なのですが.....
Orlofsky

2021/01/15 12:11

自分で試してみる気がなければ、お金を払って実行してくれる人に依頼しましょう。
guest

0

基本はインデックスのチューニングだと思いますが、単に組み替えて早くなるとしたら以下の様なSQLになるでしょう。

SQL

1 SELECT A.代理店コード, F.代理店名, A.お客様コード, Null as お客様名 2 FROM トランザクション A 3 INNER JOIN NDSS.[dbo].[代理店マスタ] F 4 ON F.代理店コード=A.代理店コード AND Not(F.削除フラグ='D') 5union all 6 SELECT A.代理店コード, Null, A.お客様コード, G.お客様名 7 FROM トランザクション A 8 INNER JOIN NDSS.[dbo].[お客様マスタ] G 9 ON G.お客様コード=A.お客様コード AND Not(G.削除フラグ='D')

前提としては結合で有効になるのはどちらかのみの場合です。
両方とも結合で有効なものはそれぞれ出力されます。

重複を発生させない場合は、下記になりますが、この場合はインデックス次第ですね。

SQL

1SELECT A.代理店コード, F.代理店名, A.お客様コード, G.お客様名 2FROM トランザクション A 3 left JOIN NDSS.[dbo].[代理店マスタ] F 4 ON F.代理店コード=A.代理店コード AND Not(F.削除フラグ='D') 5 left JOIN NDSS.[dbo].[お客様マスタ] G 6 ON G.お客様コード=A.お客様コード AND Not(G.削除フラグ='D')

投稿2021/01/19 08:07

編集2021/01/19 08:13
sazi

総合スコア25327

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2021/01/19 13:25

ありがとうございます、最初にご提案頂いたパターンの内部結合だと、GかFのマスタに存在するレコードしか表示されてこないことになりませんか???? ともあれ試してみますね、いつもすみません。
sazi

2021/01/19 23:56

それぞれで結合したものをunionしていますから漏れはありません。 逆に、両方の結合が有効なものの場合には、重複する事になるのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問