- PR -

Oracle接続時に、ヒント句を使用したい

1
投稿者投稿内容
MIRU
常連さん
会議室デビュー日: 2006/05/30
投稿数: 21
投稿日時: 2008-03-28 13:46
現在、以下のようなSQL文を使いODP.NETでOracleにアクセスしているのですが、
ヒント句の部分が機能せず困っております。

発行SQL文----------------------------------------------------
SELECT /*+ INDEX(テーブル名 キー) */ 項目1,項目2,・・・
FROM テーブル名
WHERE ROWNUM <= 100 ・・・
-------------------------------------------------------------

発行したSQL文をコピーし、SQLPLUSで動作させた所、意図したとおりに動作しており、
SQLの記述が間違っている訳ではないようです。

最終的にやりたいことは、キー順に上位100件のデータを取得することなのですが、
VBからのOracle読み込みでは、他の書き方があるのでしょか?

どなたか、ご教授お願いします。

環境
#VB.NET2003 (Framework1.1)
#Oracle 9.2.0 (ODP.NETで接続)
ほったて
ベテラン
会議室デビュー日: 2007/11/10
投稿数: 68
投稿日時: 2008-03-31 19:27
"*"をエスケープしてもだめですかね。



しかしながら、最終的に実現したいことが

引用:

MIRUさんの書き込み (2008-03-28 13:46) より:

最終的にやりたいことは、キー順に上位100件のデータを取得することなのですが、
VBからのOracle読み込みでは、他の書き方があるのでしょか?



であれば、ヒントじゃなくてorder by句の指定でしょうが。
selectの結果の順序はorder byを使わなければ一切保証されないことはマニュアルとかに記載があったかと思います。他の環境とかちょっと構文が違うSQLで取得結果が意図したとおりになるという保証はどこにもありません。

たまに当たり前すぎてマニュアルに書いてないことがあって困る...。


(あと、副問い合わせも使う必要があるなぁ)
99ri
大ベテラン
会議室デビュー日: 2006/09/09
投稿数: 129
投稿日時: 2008-03-31 22:21

ヒント句の部分が機能せずとはどういう現象ですか?
 HINT文がない状態でSQLが実行される(V$SQLで確認できます)
 SQLにHINT文があるが意図した動作ではない

INDEXはソートされた状態でデータを取り出せるため
/*+ INDEX(テーブル名 キー) */ とROWNUMで
HINT文でINDEXの順に指定件数は取得可能と思います


[ メッセージ編集済み 編集者: 99ri 編集日時 2008-04-01 05:11 ]
ほったて
ベテラン
会議室デビュー日: 2007/11/10
投稿数: 68
投稿日時: 2008-04-02 00:01
引用:

99riさんの書き込み (2008-03-31 22:21) より:

INDEXはソートされた状態でデータを取り出せるため
/*+ INDEX(テーブル名 キー) */ とROWNUMで
HINT文でINDEXの順に指定件数は取得可能と思います



where句の書き方とか他の条件の有無とか結合とか、その他諸々の要因で検索した結果の表示順は変わる可能性がありますよ。
内部のソートジョインとかのせいで全く逆の順で出てくることもありますし。



ってか過去にこの掲示板であったかどうかは見てませんが、OTNあたりでorder byせずにソートした結果を取ろうとして挫折した例は数知れずありますな。
99ri
大ベテラン
会議室デビュー日: 2006/09/09
投稿数: 129
投稿日時: 2008-04-02 05:52
引用:

ほったてさんの書き込み (2008-04-02 00:01) より:
引用:

99riさんの書き込み (2008-03-31 22:21) より:

INDEXはソートされた状態でデータを取り出せるため
/*+ INDEX(テーブル名 キー) */ とROWNUMで
HINT文でINDEXの順に指定件数は取得可能と思います



where句の書き方とか他の条件の有無とか結合とか、その他諸々の要因で検索した結果の表示順は変わる可能性がありますよ。
内部のソートジョインとかのせいで全く逆の順で出てくることもありますし。



今回はテーブルの結合もなくwhere句にROWUMのみで他の条件がありません 
indexの順番に100件ということですのでINDEX HINTとROWNUMというSQLにしたと思われます
順番の保証はORDER BY ということなのでORDER BY インデックス項目 が必要

topN分析(福問い合わせ)とHINTの併用が確実な方法であることに異議はありません

[ メッセージ編集済み 編集者: 99ri 編集日時 2008-04-02 05:58 ]
99ri
大ベテラン
会議室デビュー日: 2006/09/09
投稿数: 129
投稿日時: 2008-04-02 06:38
引用:


selectの結果の順序はorder byを使わなければ一切保証されないことはマニュアルとかに記載があったかと思います。他の環境とかちょっと構文が違うSQLで取得結果が意図したとおりになるという保証はどこにもありません。

たまに当たり前すぎてマニュアルに書いてないことがあって困る...。



Oracle10gR2のSQLマニュアル
otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/statements_10.html#12698

ORDER BY句を使用すると、文によって戻された行を順序付けることができます。
order_by_clauseを指定しない場合
同じ問合せで取り出される行の順序が異なることがあります。

==>同じになることは保証していない
DSCH
常連さん
会議室デビュー日: 2005/10/23
投稿数: 24
投稿日時: 2008-04-03 00:38
スレ主さんのやり方って、韓国のコンサルの方が書いた
「データベースパフォーマンスアップの教科書 基本原理編 」
って本紹介されていたのを見たことがあります。
この本DBはOracleを想定しているようです。

http://www.en-core.co.jp/db/db_books.asp

目次の
第2部 アクセスの最適化の策定 311
第5章部分範囲処理(Partial range scan) 313
5.4 部分範囲処理への誘導 329
5.4.1 アクセスパスを利用したソートの代替

という部分に記述がありました。
一番最初の条件判定に使用される条件にインデックスが使用されるなら、
物理的なアクセスがそのインデックス順になるというのが根拠のようです。
(他の条件が単なるフィルター条件になる場合だけとか制約はあるかもしれませんが)

インラインビュー内で ORDER BY して外側でrownumを条件に
しちゃうと条件にあう全レコードを調べてから並べ代えてTOP N件取得だけど、
ヒント句とwhere key > MIN_VALUE とかで誘導する
このやり方なら全レコード判定せずともN件見つけた時点で処理を確定できるとか。

確かに実行計画見るとインラインビューでorde by したときには
count stop key の内側で sort order by してます。
実際どうなんでしょうか?
ほったて
ベテラン
会議室デビュー日: 2007/11/10
投稿数: 68
投稿日時: 2008-04-05 16:50
引用:

DSCHさんの書き込み (2008-04-03 00:38) より:

インラインビュー内で ORDER BY して外側でrownumを条件に
しちゃうと条件にあう全レコードを調べてから並べ代えてTOP N件取得だけど、
ヒント句とwhere key > MIN_VALUE とかで誘導する
このやり方なら全レコード判定せずともN件見つけた時点で処理を確定できるとか。

確かに実行計画見るとインラインビューでorde by したときには
count stop key の内側で sort order by してます。
実際どうなんでしょうか?




うーん、副問い合わせの書き方次第じゃないですか?
うちの環境では"INDEX FULL SCAN"したようですが(ただし単なるorder byだけじゃなくdense_rank使ったりしましたけど)。

第一、order by省きたいがために実行計画を云々するってのもどうでしょうかね。統計情報の内容と条件指定の有無によっちゃ逆順でソートされる可能性もあるだろうに。
それに無理な実行計画の誘導でパフォーマンスに影響が出たりした日にはもう...。




そういや索引構成表なんてものもOracle 8の時代からあったな。あれで代用できないもんかな...。
1

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