次のような非常に遅いクエリがあります。
SELECT *
FROM (
SELECT ..., nn_key_fast(nachname) nnk, ...
FROM t1
JOIN t2 ON
...
JOIN t3 ON
...
JOIN t4 ON
...
WHERE ...
AND t4.POSTCODE='1234'
)
WHERE ... AND nnk LIKE "N%"
現在、内部選択には約2分かかります。最後のWHERE句(t4.POSTCODE)を削除すると、約4秒で実行されます。この句がない場合の結果は1000レコード未満になるため、非常に小さなセットになります。
したがって、私の考えは、その句を外部のSELECTに移動すると、結果の1000未満のレコードにのみ適用されるというものでした。
しかし、違います。クエリにはまったく同じ時間がかかるため、明確にするために次のようにします。
SELECT *
FROM (
SELECT .....
FROM t1
JOIN t2 ON
...
JOIN t3 ON
...
JOIN t4 ON
...
WHERE ...
)
WHERE ...
AND POSTCODE='1234'
最初のバージョンと同じ2分かかります。
これは私には非常識に思えます。
直感的には、これは次のようにクエリオプティマイザによって実行する必要があります。次のように内部選択からテーブルを作成します。
CREATE TABLE res_from_inner AS (
SELECT .....
FROM t1
JOIN t2 ON
...
JOIN t3 ON
...
JOIN t4 ON
...
WHERE ...
)
...次に、次のように、このテーブルでのみ外部選択を実行します。
SELECT *
FROM res_from_inner
WHERE POSTCODE='1234'
また、これを手動で行うと、CREATE TABLEクエリには約4秒かかり、2番目のSELECTには予想どおり1秒未満かかります。
これはどのように可能であり、それに対して何をすべきですか?
実際に何が起こっているかを確認するには、実行プランを確認する必要があります。何かが変わっています。
あなたが試みるかもしれない1つのことはCTEです:
with s as (
<subquery here>
)
select s.*
from s
where . . .;
Oracleはこれを自動的に実現する可能性があります。または、ヒントを与えることができます:
with s as (
select /*+ materialize */ . . .
. . .
)
select s.*
from s
where . . .;
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加