たとえば、以下のA01KINGAKUテーブルがあったとして
KAISHA CHAR(2) (主キー)
KINGAKU NUMBER(15)
このテーブルに1万件のデータが入っていて
各レコードのKAISHA項目は、全て 'A1'
だったとしたとき
Select * from A01KINGAKU where KAISHA = 'A2'
としたときに、
インデックスをみれば、A2が存在しないというのは
すぐにわかりそうなものですが、
Oracle 10gで、これをしたら、全件検索されてしまいました。
(統計情報は直前に取得済みです)
たぶん、インデックスの値に散らばりがないので
インデックスを使わないという判断になったのだと思いますが
インデックスを強要する術はないでしょうか?
/*+index(A01KINGAKU インデックス名)+*/ とすればよいのでしょうが
こうしたことを多数のテーブルについてやりたく
いちいちインデックス名を調べるのがわずらわしく
インデックス名がいらないヒントの方法あるいは
ヒントとはまったく違った方法を探しています。
(そもそもそんなもの主キーにするなとか、質問の意図が読めないというご意見もあるかと思います。
元は、ALLKINGAKUテーブルという複数のKAISHAコードを扱うテーブルがあって、これを処理速度向上のため、
KAISHAコードごとにテーブルを分割し、
ALLKINGAKUテーブルを廃止して、代わりに
select * from A01_KAISHA union all select * from A02_KAISHA ...
としたALLKINGAKUビューを作成したと思ってください。
この時、Select * from ALLKINGAKU where KAISHA = 'A02'としたときに、ビュー上で、A01_KAISHAまで全件検索されてしまったことに
端を発している質問です)
No.1ベストアンサー
- 回答日時:
うーん、混乱する質問ですね。
整理すると、(1)ALLKINGAKUビューが下記のとおり作成してある。
Select * from A01KINGAKU
union all
Select * from A02KINGAKU
union all
Select * from A03KINGAKU
(2)A01KINGAKU、A02KINGAKU、A03KINGAKUテーブルにはそれぞれ
KAISHA項目があり、インデクスが貼ってある。
(3)このビューに対して
Select * from ALLKINGAKU where KAISHA = 'A2'
と検索したら
A01KINGAKUテーブルを全件検索していた気がする。
A01KINGAKUテーブルを全件検索してないと思うには、
または該当するテーブルだけを検索するようにするにはどうしたらいいですか?
という質問ですか?
パーティションテーブルを使ったらどうでしょうか。
SQL実行計画は見ましたか?
全件検索(TABLE ACCESS FULL)ではなく索引検索(INDEX RANGE SCAN)になっていませんか?
この回答への補足
コメントありがとうございます。
はい、質問の意図はご指摘の通りです。
A01KINGAKU, A02KINGAKU , A03KINGAKUすべてが全件検索されています。
実行計画は確認しております。
パーティションテーブルは、Enterprise以上でないと使えないので
このようなテーブル構成を自作しているようです。
No.2
- 回答日時:
こんにちは。
インデックスが意図した形で機能してくれない、
ということなんですが、オラクルでインデックスが機能しない
ケースというのはご存知でしょうか?
オラクルでは全レコード数の確か5%程度の結果が得られる場合に、
インデックス検索を行うというそうです。
つまり、極端な話ですと、1万件の中から9999件のレコードを
取得するのに、いちいちインデックスを使うよりも、
テーブルを総なめしたほうが高速である、ということです。
オラクルはこれを自動的に判断しています。
提示された例で考えると、テーブル内には1万社分のレコードが
登録されていて、テーブルに存在しないキーを条件につけた場合、
ということでの相談なっていますが、ただ単にレコードの有無だけを
判断するのでしたら、COUNT(キー項目)をとるのが良いと思います。
「*」を使うと、カーソルを使用したり、不要なフィールドへの
アクセスが発生し、パフォーマンス的にも悪影響を及ぼします。
ですので、キー項目のカウントを取ることによって、
全体のパフォーマンスは向上すると思いますよ。
#1さんへの回答にありますように、索引の全体検索となっている
だけですと、それが現状の最高パフォーマンスといえますが、
全表検索が走っているようであれば、そのテーブルの設計に問題が
あるようにも感じられます。
現状1万件程度のデータで、どれくらいのパフォーマンスを発揮して
いるのでしょうか?
私も色々とチューニングを経験してきましたけど、最もボトルネックが
潜んでいるといえるのが、実は実行する SQL 文だったりします。
あと最後にアドバイスですが、ビューは SQL 文を見やすくはしますが、
落とし穴になりがちです。
実際、SQL を実行した際には最初に実行されるのがビューの部分です。
ここで巨大な2つのテーブルを JOIN しているようなら、
そこがボトルネックになります。
2つのテーブルを、その段階で全表検索します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Oracle SQL update方法 2 2022/06/22 14:07
- Oracle 下記のsqlで取得されるレコード以外を取得する方法ありますでしょうか。 SELECT B.番号, B 2 2022/04/20 23:21
- MySQL 複数DBテーブルからのデータ取得 3 2022/05/17 15:02
- Oracle sqlで質問です。 aテーブルとbテーブルがあり、下記のsqlで取得したidとnameに一致しないレ 1 2022/04/20 20:34
- MySQL 書籍の内容はまともでしょうか? 1 2023/01/22 03:07
- PHP クエリObjectをforeachで回す時に、次のレコードへ移動せずに次のレコードを取得したい 2 2022/07/28 15:29
- Oracle 質問です。 下記のテーブルとデータがあり、 取得想定結果のように出力したいです。 下記のsqlだと0 2 2023/05/23 19:10
- Ruby pandasでsqlite3にテーブル作成・追加・読み出しでindexの取り扱い方教えてください 5 2023/03/08 09:57
- MySQL 共通点はあります。何が違うのでしょうか? 1 2023/01/27 05:22
- MySQL PhpMyAdminで作成して実行せよ。 東京23区を、皇居を中心とした4つのエリア(南東, 南西, 1 2023/06/11 11:58
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SQL*Loaderで、データを加工し...
-
アナライズとインデックス作成...
-
索引の再構築をすべき?
-
Oracle Databaseのインデックス...
-
インデックス作成後アナライズ...
-
oracle10g統計情報取得の確認方法
-
Data Pump で大量データインポ...
-
ORA-00959: 表領域'****'は...
-
RDBのテーブル種類の違い
-
INSERT文で発行したオートナン...
-
postgreSQLのint型は桁数指定が...
-
1つのテーブル・2つの列を結合...
-
列が255以上のCSVファイルをAcc...
-
accessでイベントを中止するよ...
-
count(1)とcount(*)の違い
-
ある英語の問題のコト
-
C#でaccdbファイルのテーブルの...
-
ACCESSとエクセルのリン...
-
他の処理でselectさせないよう...
-
同じSELECT文同士でのデ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Viewにインデックスは張れ...
-
INDEXの無効化
-
SQL*Loaderで、データを加工し...
-
可変個数のデータはどう納める?
-
アナライズとインデックス作成...
-
主キー以外の項目にNotNull制約...
-
論理読み込みブロック数とは?
-
テスト環境と本番環境で、DBか...
-
文字列中のスペースを排除する...
-
インデックス作成後アナライズ...
-
索引の再構築をすべき?
-
Wordで複数の索引を作りたい
-
Oracle Databaseのインデックス...
-
統計情報について
-
SQLのIN句について
-
SQL*LoaderとInsertの違いについて
-
OracleTextの索引再構築について
-
目的のインデックスが使用され...
-
blevel=3のデータ作成
-
オラクル クラサバ環境で動作...
おすすめ情報