- PR -

複合索引

投稿者投稿内容
zilloll
常連さん
会議室デビュー日: 2006/02/01
投稿数: 24
投稿日時: 2006-02-02 17:57
TBL_B(MASTER_TBL_B)に主キー設定されているとのことですので、
TBL_Aにインデックスがあるかないかで以下のようになると思います。

[インデックスあり]
TBL_A:RANGE SCAN
TBL_B:全件検索

[インデックス無し]
TBL_A:全件検索
TBL_B:UNIQUE SCAN

ただ、どの構成が最も最適かというと、各テーブルの
データ量にもよると思います。

たとえば、TBL_Aに大量のレコードがあり、TBL_Bには小量のデータしか
ないといった場合には、TBL_Bは全件検索で、TBL_Aに対し
INDEXを使った検索を行ったほうが早くなると思います。
ちなみにTBL_Aにインデックスを張る場合は、単一索引より、
複合索引のほうが速いのではないでしょうか。

[ メッセージ編集済み 編集者: zilloll 編集日時 2006-02-02 18:10 ]
あんとれ
ぬし
会議室デビュー日: 2004/01/14
投稿数: 556
投稿日時: 2006-02-02 18:07
引用:

guest98さんの書き込み (2006-02-02 17:20) より:

SELECT
 A.SYURUI,
 A.KAZU,
 B.MAKER,
 B.S_NO
FROM
 TBL_A A,
 MASTER_TBL_B B
WHERE A.H_CD = B.H_CD
AND  A.C_CD = B.C_CD
;

TBL_A : H_CD,C_CDには単一列索引(主キーは他の列、主キー列は使用しない)
MASTER_TBL : H_CD,C_CDの2列で主キー

zillollさんの解説からすると、この状態がベストということでしょうか?



設計としては、

TBL_A : H_CD, C_CD の2列で複合索引、必要に応じて C_CD に単一列索引
MASTER_TBL : H_CD, C_CD の2列で主キー

がよいのではないかと思いますが・・・。

実際にはデータ件数によって、両方テーブルを単純にタスキ掛け方式でフルスキャンした方がいい場合もあります。また、最近の RDBMS はハッシュ結合をサポートしているため、索引がなくても高速に結合できる場合もあります。

[ メッセージ編集済み 編集者: あんとれ 編集日時 2006-02-02 18:10 ]
guest98
常連さん
会議室デビュー日: 2006/02/02
投稿数: 22
投稿日時: 2006-02-03 10:03
現時点で、TBL_Aには130万件、TBL_B(MASTER_TBL)には7万件のデータが入っています。
両テーブルとも、今後もデータ件数は増えていきます。

インデックスの張りなおしは時間がかかるので、なかなか自由には出来ないのですが、
パフォーマンスアップを期待して、TBL_Aを複合索引にしてみようと思います。
guest98
常連さん
会議室デビュー日: 2006/02/02
投稿数: 22
投稿日時: 2006-02-03 10:54
速くなりました!

皆さん、ありがとうございました!
guest98
常連さん
会議室デビュー日: 2006/02/02
投稿数: 22
投稿日時: 2006-02-03 11:29
解決したはずなのに、すいません。
以下のSQLを試してみたところ、BUFFER_GETSがものすごく高いんです。
これはメモリ上で全件検索が行われているということなんでしょうか?

複合索引にして、以前よりは速くなったのですが、
確かに遅いのです。データ件数が多いから仕方がないと思っていたのですが、
まだ改善の余地があるのでしょうか?

SELECT
 S.EXECUTIONS,
 trunc(S.DISK_READS/EXECUTIONS, 0) AS DISK_READS,
 trunc(S.BUFFER_GETS/EXECUTIONS, 0) AS BUFFER_GETS
FROM V$SQL S
;
---------------------------------------------------
3 0 332465
3 0 230840
zilloll
常連さん
会議室デビュー日: 2006/02/01
投稿数: 24
投稿日時: 2006-02-03 13:44
一度検索を行うと結果をメモリにキャッシュするので、
同じSQLが実行されるとキャッシュが利用されるはずです。
(これまでの話から、DBMSはOracleと判断しています)
単純な結合だけなので、毎回130万件のデータを取得することになり
メモリもかなり使用することが予想されます。
元のSQL文がシンプルなのでこれ以上チューニングというと
私の知識では、申し訳ないのですが、ちょっと思いつきません。
それだけ大量のデータにアクセスするとなると、
もし可能ならば、毎回全てのデータを取得する必要があるのか
検討したほうがよいようにも思います。

[ メッセージ編集済み 編集者: zilloll 編集日時 2006-02-03 13:46 ]
もしもし
ぬし
会議室デビュー日: 2004/10/15
投稿数: 280
投稿日時: 2006-02-03 13:48
引用:

guest98さんの書き込み (2006-02-03 11:29) より:
解決したはずなのに、すいません。
以下のSQLを試してみたところ、BUFFER_GETSがものすごく高いんです。
これはメモリ上で全件検索が行われているということなんでしょうか?

複合索引にして、以前よりは速くなったのですが、
確かに遅いのです。データ件数が多いから仕方がないと思っていたのですが、
まだ改善の余地があるのでしょうか?



アクセス対象のデータ量が多くなればしょうがない部分もあるでしょうが、
同時アクセス数が多くなれば、buffer busy waits とかの待機が顕在化する
可能性はあるでしょうね。
データの整理とかパーティション分割とか条件指定の調整とかも検討すべきかも。

_________________
もしもし@RMAN 友の会
guest98
常連さん
会議室デビュー日: 2006/02/02
投稿数: 22
投稿日時: 2006-02-03 14:23
あ、すいません。説明不足でした。。。
検索条件は実際には色々たくさんあるんです。

WEB上で、売り上げの分析をするためのシステムなので、
日付や商品や会社で絞ります。
FROM句でもサブクエリで絞ってます。

集計が必要なので、毎回GROUPBYが入ります。
となると、やっぱり遅いのは仕方ないですかね...

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