- PR -

クエリアナライザの実行プランについて

1
投稿者投稿内容
ケイ
大ベテラン
会議室デビュー日: 2004/04/20
投稿数: 100
投稿日時: 2005-08-10 17:50
現在、Vb6+MSDEで開発を行っているのですが、データ集計を行っている箇所に
時間がかかってしまう為、SQLのチューニングを行っております。

http://www.microsoft.com/japan/msdn/sqlserver/columns/sysbuild/sysbuild3.asp
上記を参考に作成したSQL文のサブツリーコストが低いSQL文を作成していたのですが、
Hash 結合を行った場合の方が、サブツリーコストの値が大きいのに、
実際時間を比べると、2秒早いのです。

そこで、実行プランの見方、参考となるホームページ等を教えて頂きたいです。
※サブツリーコストが低い方が処理は速いのではないのですか??

SQL文は、
select b.Kcode,b.STcode,d.Scode,c.Jcode5
FROM M1 b
Inner join D1 c ON b.Kcode = c.Kcode
Inner join TK a On b.Kcode = a.Kcode
Left outer join MC g On b.STcode = g.STcode
Left outer join MJ h On c.Jcode1 = h.Jcode 
inner join MS d On a.Scode = d.Scode

PRIMARY KEYの指定は下記になっています。
M1 テーブルの Kcode 列
MJ テーブルの Jcode 列
MS テーブルの Scod 列
MC テーブルの STcode 列
D1 テーブルの Kcode 列と Jb 列

Kcodeは、顧客に与えられた番号になります。
Jcodeは、お店の従業員に与えられた番号です。
Scodeは、商品に与えられた番号です。
STcodeは、グループ番号で、顧客はこのグループ番号に割り振られています。

D1テーブルは、Kcode,Jb,Jcode1〜Jcode31の列を持っていて、
一日毎に顧客に対して、担当する従業員がJB分割り振られています。

Jcode1〜Jcode31に登録されている値を取得したい為、上記のSQLを
Loopで31回(c.Jcode1の部分を変更して)発行している状態です。

で、上記のSQL分の場合、実行プランは
全部のテーブルがNested Loops/Inner join で結合し、
Select分のサブツリーコストは、0.0396です。

下記のSQLに変更した場合、
select b.Kcode,b.STcode,d.Scode,c.Jcode5
FROM M1 b
Inner Hash join D1 c ON b.Kcode = c.Kcode ←ここだけHashにする。
Inner join TK a On b.Kcode = a.Kcode
Left outer join MC g On b.STcode = g.STcode
Left outer join MJ h On c.Jcode1 = h.Jcode 
inner join MS d On a.Scode = d.Scode

実行プランは、M1テーブルとD1テーブルがHash Match/Inner joinで結合し。
他がNested Loops/Inner join で結合し、
Select分のサブツリーコストは、0.119です。

速度の検証は、クエリアナライザで、コストの低いSQL文にした後、
VBの処理部分のSQLを修正し、
VBの中で、時間を計っています。
何度計っても、2秒Hashを付けた方が早いのです。

実行プランの内容から、どこをどのように判断して、
効率のよいSQLであるとなるのでしょう?
そうだとしても、実際の処理時間には関係ないのでしょうか?
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2005-08-10 18:09
@ITにあるページでしかもOracleですが、
考え方は基本的に一緒だと思うので、リンク張っておきます
http://www.atmarkit.co.jp/fdb/rensai/orasql10/orasql10_1.html
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2005-08-11 07:15
一般的な話ですが、件数がかなり多いテーブル同士をJOINするときはハッシュ結合が有効な手段となることが多いです。逆に件数が少ないとハッシュ値を生成するコストのほうが大きくなるので適しません。
ケイ
大ベテラン
会議室デビュー日: 2004/04/20
投稿数: 100
投稿日時: 2005-08-11 09:19
引用:

Anthyhimeさんの書き込み (2005-08-11 07:15) より:
一般的な話ですが、件数がかなり多いテーブル同士をJOINするときはハッシュ結合が有効な手段となることが多いです。逆に件数が少ないとハッシュ値を生成するコストのほうが大きくなるので適しません。



なるほど。件数にもよるのですね。

ただ、私が試した環境では、今の所どのテーブルにも20行程度のデータなのです。
なのにハッシュ結合の方が早かったという事は、そこが鍵となりますよね。
違いといえば、ハッシュ結合をした場合のテーブル結合順が変わっていました。

ハッシュを行わないで、テーブル結合順が同じになるようにして試して見ます。
ケイ
大ベテラン
会議室デビュー日: 2004/04/20
投稿数: 100
投稿日時: 2005-08-11 13:30
テーブルの結合順が同じになるように試しては見たのですが、
Hashの方が早かったです。

ただ、データを大量にした場合は、Hashを付けない方が早かったです。

各テーブルは、clusteres Indexseekでスキャンされていますが、
そのテーブルコストがHashを付けない場合、
全部のテーブルがだいたい17%なのに対し,Hashを付けた場合、
Hashで結合しているテーブルが65%と17%。
他のテーブルは0%になっていました。

この違いから、サブツリーコストはHashの方が大きくても,
使用するテーブルのコストが、低いため、多少早いのでしょうか?

1

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