すいません、VB4しかやってないんです、VBAはやったけど(ぼそ) チラシの裏だって立派な書き込み空間なんだからねっ!資源の有効活用なんだからねっ!とか偉そうに言ってるけど、実は色々と書き残したいだけ

だからなに? どうしろと? くるみサイズの脳みそしかないあやしいジャンガリアンベムスターがさすらう贖罪蹂躙(ゴシックペナルティ)

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  632  : 記事  35  : コメント  11686  : トラックバック  143

ニュース


片桐 継 は
こんなやつ

かたぎり つぐ ってよむの

大阪生まれ河内育ちなんだけど
関東に住みついちゃったの
和装着付師だったりするの
エセモノカキやってたりするの
VBが得意だったりするの
SQL文が大好きだったりするの
囲碁修行中だったりするの
ボトゲ好きだったりするの
F#かわいいよF#

正体は会った人だけ知ってるの

空気読まなくてごめんなさいなの


わんくまリンク

C#, VB.NET 掲示板
C# VB.NET掲示板

わんくま同盟
わんくま同盟Blog


WindowsでGo言語
WindowsでGo言語


ネット活動


SNSは疲れました

記事カテゴリ

書庫

日記カテゴリ

ギャラリ

イベント活動

プログラムの活動

A1
 A_ID (PK)
 A_ID

A2
 A_ID (PK)
 C_ID
A3
 C_ID (PK)
 C_Code
 C_Name

というテーブルがあったとする。
判っているのは A1_ID で、このA1_IDからA2テーブルをたどって、A3テーブルの情報をとりたい、とする。

このときに使いたいSQLには色々とあるとおもうのだけれど以下の二つがある、とする。

SQL-Server2005で実行する場合、早いのはどっち~?

(1)

SELECT A3.C_ID, A3.C_Code,
 A3.C_Name
 FROM A3
  INNER JOIN A1 ON
    A1.A_ID=150
  INNER JOIN A2 ON
    A2.A_ID = A1.A_ID AND
    A2.C_ID = A3.C_ID
 ORDER BY A3.C_ID 

(2)

SELECT A3.C_ID, A3.C_Code,
 A3.C_Name
 FROM A3 WHERE C_ID =
 (SELECT C_ID FROM A2 WHERE A_ID =
 (SELECT A2 FROM A1 WHERE A_ID = 150))
 ORDER BY A3.C_ID 

答え、検索元テーブルレコード数、抽出対象レコード数が少ないと実はあんまり変わんない(死)
けれどデータ量が増えたとき、早いのは(1)みたい(^^;

実は、実際にSQLの実行プランを表示してみると両者の違いがはっきりと出るのです。諸事情によりプラン図出せないので、文章になりますけれど……

(1)の場合
A2とA3クラスターインデックスで検索→NestedLoops→結果とA1のクラスターインデックス結果でNestedLoops→結果

(2)の場合
A2とA3クラスターインデックスで検索→NestedLoops→結果をStreamAggregate→Assert→
結果とA1のクラスターインデックス結果でNestedLoops→結果

消費コストはどちらも同じで、最後のNestedLoopsで3%、残りを3つのクラスターインデックス検索で分けています。つまり、SELECT文を使用した場合には、インデックスで検索した後で「これ、いる?いらない?」の判断処理が入っていてレコードの取捨選択があり、その分処理のステップが増えているんですね。INNER JOIN命令っていうのは「取捨選択?そんなの関係ねぇ!」ばりにくっつくデータをを無条件に持ってくる、と。」

データ量が少ない時にはそんなに意識しなくっても良いし、それこそ標準化と可読性に重きを置いておいても良いのかもしれない。でも、データ量が増える可能性があるときに備え、データ量が多いテーブルでのデータ処理、テーブルキー関係と正規化を把握して、できるだけ処理コストとステップを抑えたSQLが書けるようにしておくと良いかも、ですです。

投稿日時 : 2007年11月12日 23:53

コメント

# re: 結果はおんなじ何だけど 2007/11/13 1:05 けろ
なるほどね。(2)の方が余計なステップ踏んじゃってる分、大量データの場合は差が出るってわけね。
納得!(実行結果のハードコピーが見たかったなぁ~w)
私の場合は、絶対、(1)で書きますけどねw
(2)は、どちらにせよ、わかりづらいwww



# re: 結果はおんなじ何だけど 2007/11/13 2:42 Streetw☆
私は(2)の書き方します。
2の方がわかりやすくて見やいから!
っっって、けろさんと意見が正反対(;_;)
ま、人それぞれということでww

ところで、いろいろタイプミスがあるみたいだけどw、例えばA2のテーブルだとC_IDは一意にはならないから WHERE の条件は IN じゃないとダメですよね?
#Oracleな感覚で書いてますので、SQL Serverでは大丈夫だったらごめんなさいw


# re: 結果はおんなじ何だけど 2007/11/13 3:07 Streetw☆
あ、あ、私、間違ってます。
INじゃなくていいです。。。ごめんなさい。

# re: 結果はおんなじ何だけど 2007/11/13 9:37 Streetw☆
昨日は2がいいと書いたけど、1がやっぱりいいかもw
でも私の場合は次のみたく書くと思います。
パフォーマンスって同じですよね?

(1-2)
SELECT A3.C_ID, A3.C_Code,
 A3.C_Name
 FROM A3
  INNER JOIN A2 ON
   A3.C_ID = A2.C_ID
  INNER JOIN A1 ON
   A2.A_ID = A1.A_ID
 WHERE
  A1.A_ID = 150


# re: 結果はおんなじ何だけど 2007/11/13 21:41 片桐
>けろたん
そうそう、そういうことみたい

>Streetw☆さん
まいどー♪
また、良いネタもって来ましたね(^-^)
正解!SQL-Serverでは、(1)と(1-2)では同じアルゴリズムで動きます。私の知る限りのOracleでは、内部ヒントが変わるので動きが異なるはず(笑)

ここがSQL-ServerとOracleの違い、面白いところなんですよね~♪

Post Feedback

タイトル
名前
Url:
コメント