- PR -

Oracle データ検索速度相違について

投稿者投稿内容
茶太郎
ベテラン
会議室デビュー日: 2005/02/23
投稿数: 57
投稿日時: 2005-03-28 11:11
お世話になります。
初心者のため現在以下の内容で悩んでおります。

(テーブルA)
データ件数:25万件程度
(テーブルB)
テーブルAとテーブル名のみ相違させて複製したテーブル

この2つのテーブル同SQL(テーブル名のみ相違)を流したところ
検索にかかる時間が大きく相違しました。
※SQLは区分を格納している列で存在している区分を重複なしで
 取得するという簡単なものです。
※もちろんINDEXは関係ありません。
 TABLE ACCESS FULL

実行計画を確認してみると以下の項目に相違がありました。
 physical reads (ディスクへのデータ要求数)

何度テーブルAに対し同SQLを流してもphysical readsは同じで
検索にかかる時間も同じです。
テーブルBはphysical readsが0(ゼロ)となります。

なぜこのようなことが起こるのでしょうか?
やはりテーブル作成時に問題あるのでしょうか?

どなたかご存知の方おられましたら教えてください。
宜しくお願いします。

ちなみにDBはOracle8.1.7です。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2005-03-28 11:38
引用:

茶太郎さんの書き込み (2005-03-28 11:11) より:
テーブルBはphysical readsが0(ゼロ)となります。


physical reads = 0(ディスクから読み出したデータ量が0)と言う事は、SQL文を実行したときたまたまデータが全てメモリ上にキャッシュされていたのでしょう。HDDにアクセスしなかった分、動作が速かったのでしょうね。

一度データベースをシャットダウンした後、データがキャッシュされていない状態でSQL分を実行すれば同じ結果になりませんか?
_________________
甕星 <mikahosi@abox9.so-net.ne.jp>
http://blogs.msmvp.jp/mikahosi/
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2005-03-28 11:39
元々存在しているテーブルAに対する更新処理はどのような事を行っていますか?
Delete/Insertが多発するとか・・・。
またテーブルBにデータを作成するときはどのような方法を取られてますか?
茶太郎
ベテラン
会議室デビュー日: 2005/02/23
投稿数: 57
投稿日時: 2005-03-28 12:08
甕星さん、夏椰さん早速の返信ありがとうございます。

一度DB再起動させて試してみますが、なぜ片方のSQL文のみ
メモリ上にキャッシュされ片方はメモリ上にキャッシュされな
いという現象が起こるのでしょうか?

ちなみにテーブルAに対する更新処理は夜間で一旦Truncateし、
その後Insert(1件毎コミット、25万件程度)を日々繰り替えして
いるテーブルです。

それとテーブルBにデータを作成するときは以下で移行しています。
INSERT INTO テーブルB (SELECT * FROM テーブルA);
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2005-03-28 12:58
引用:

茶太郎さんの書き込み (2005-03-28 12:08) より:

ちなみにテーブルAに対する更新処理は夜間で一旦Truncateし、
その後Insert(1件毎コミット、25万件程度)を日々繰り替えして
いるテーブルです。

それとテーブルBにデータを作成するときは以下で移行しています。
INSERT INTO テーブルB (SELECT * FROM テーブルA);



テーブルBにデータを作成する処理を実行した直後に
テーブルA、テーブルBにデータ取得するSQLを実行していたら
テーブルBの方が早いかもしれません。
テーブルBを作ったバッファが残っているので。
茶太郎
ベテラン
会議室デビュー日: 2005/02/23
投稿数: 57
投稿日時: 2005-03-28 13:56
夏椰さん、ありがとうございます。

一度テーブルA、テーブルBにデータが入っている状況で
DB再起動し再度同内容のSQLをテーブルA、テーブルBに
流したところ、physical readsはほぼ同じになったのですが
consistent getsとredo sizeが相違してしまいました。
が、検索速度はほぼ同じでした。

その後、両テーブルに再度SQLを流したところどちらの
physical readsも0(ゼロ)となりました。
※consistent getsとredo sizeも同じとなりました。

ここで疑問なのですが、再起動前に何度かテーブルAに対して
同SQLを流しているのにphysical readsが0(ゼロ)にならなかったの
でしょうか?

もちろんテーブルBに対してのphysical readsも一発目の
SQLの時は0(ゼロ)ではなたっかのですが、2発目から0(ゼロ)となりました。

この辺りご存知であれば教えてください。
宜しくお願い致します。
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2005-03-28 14:36
引用:

茶太郎さんの書き込み (2005-03-28 13:56) より:
ここで疑問なのですが、再起動前に何度かテーブルAに対して
同SQLを流しているのにphysical readsが0(ゼロ)にならなかったの
でしょうか?

もちろんテーブルBに対してのphysical readsも一発目の
SQLの時は0(ゼロ)ではなたっかのですが、2発目から0(ゼロ)となりました。

この辺りご存知であれば教えてください。
宜しくお願い致します。



あくまで推測ですが・・・
バッファキャッシュは「頻繁にアクセスされるブロックや新しいブロックをできるだけキャッシュ上に保持する仕組み」になっているので、
テーブルAへのアクセスが少なく、他のテーブルにアクセスする頻度が高かったりするとテーブルAのデータはバッファから追いやられちゃったりするのでは・・・?
再起動後は他テーブルに対するアクセス頻度の高い処理が動く前だったりで、
テーブルAのバッファが追いやられずに済んでいるのかもしれません。
テーブルBはアクセス頻度の高いデータのバッファサイズを差し引いても、バッファ内に
全データを格納できる状態だったか…。

実際に動いている環境や発行されているSQLを見て、バッファがどんな状態かを
考えていかないと一概には言えないのですが・・・。
茶太郎
ベテラン
会議室デビュー日: 2005/02/23
投稿数: 57
投稿日時: 2005-03-28 15:31
夏椰さん、ありがとうございます。

ご指摘頂いたところを調べてみようと思います。
まったくまだ分からないのですが、どうもバッファから追いやられたと
言うよりは、キャッシュされないような気がします。

ちなみに該当データがデータベース・バッファ・キャッシュにあるかどうかを
確認することは可能なのでしょうか?

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