1

タイプタイムゾーンの列を持つテーブルがあります。この列は索引付けされています。

このクエリは次のインデックスを使用します。

select t.*
from <table> t
where t.load_date = to_timestamp('1 may 2013', 'dd mon yyyy') 
order by t.load_date;  

これ (タイムゾーン変換を追加) は機能せず、インデックスの使用を強制するように示唆しても機能しません。

select t.*
from <table> t
where t.load_date = to_timestamp('1 may 2013', 'dd mon yyyy') at time zone 'US/Pacific'
order by t.load_date;  

後者のクエリに FTS が必要な理由を誰か説明できますか?

ありがとう。

4

1 に答える 1

0

load_datetimestampではなく であると仮定するとtimestamp with time zone、説明計画は次のようになります。

filter=SYS_EXTRACT_UTC(INTERNAL_FUNCTION("LOAD_DATE"))=
    SYS_EXTRACT_UTC(TIMESTAMP('2013-05-01 00:00:00000000000' AT TIME ZONE 'US/Pacific'))

列が左側にある場合は、左側に呼び出しがなく、フィルターとしてではなく、アクセス (つまり、インデックス ルックアップ) に使用できますtimestamp with time zoneINTERNAL_FUNCTION()

access(SYS_EXTRACT_UTC("LOAD_DATE")=
    SYS_EXTRACT_UTC(TIMESTAMP('2013-05-01 00:00:00000000000' AT TIME ZONE 'US/Pacific'))

列はあるタイプから別のタイプに内部的に変換する必要があり、変換された値をフィルター値と比較する前に、すべての行に対して行う必要があります。その場合、Oracle はインデックスを使用しません。通常、明示的または暗黙的な関数をインデックス付きの列に適用する必要がある場合は使用しません。

(ほぼ間違いなく、フル インデックス スキャンを使用して変換する値を取得できますが、フィルターに一致する数がわからないため、実際のテーブルから非常に多くの行を取得する必要があり、それでも終了する可能性があります。このような決定を内部でどのように行っているかはわかりません.私の経験では、インデックスを無視しているだけです.興味深いことに、SYS_EXTRACT_UTC呼び出しは例外のようです)。

于 2013-07-10T08:46:56.303 に答える