データベースで長いこと遠く離れた開発者が、述語の書かれた順序に依存している問合せを作成しました。例えばOracle 12cインライン・ビュー評価
、
select x
from a, b
where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
and a.char_column = b.numeric_column;
(計画は
to_number
変換は
a.char_column
に適用されます示唆して説明)
私はこの "だけの作品"(Oracle 11gの)を設計よりも多くの偶然だと思います。ただし、Oracle 12cで実行しているときには述語の順序が守られていないため、この問合せは無効な例外で破損します。私は
select /*+ ORDERED_PREDICATES +*/ x
from a, b
where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
and a.char_column = b.numeric_column
を次のように私はORDERED_PREDICATES
ヒントを使用して順番に述語を評価するために12Cを強制的に試みることができることを承知している。..や比較のためto_char
を使用して値のいずれかをキャスト。欠点は、to_char
が100万行で動作できることです。私は次のインラインビューはおそらくより良い解決策だと思う。インラインビューが最初に評価されることを保証していますか?
select x
from b
inner join (
select only_rows_with_numeric_values as numeric_column
from a
where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
) c
on c.numeric_column = b.numeric_column;
あなたはbテーブルに何百万もの行があると言っています( '欠点はto_char could op例えば100万行になると言う。暗黙的な変換が行われるため、to_number関数が適用されるため、表の中にいくつの行がありますか?テーブルに同じ(またはそれ以上の)行がある場合、to_charのためにパフォーマンスに悪影響を与えることはありません。 – Boneist
また、数値aのみを含むテーブルaに仮想列を作成し、その列にインデックスを付けることができます。クエリは、 'a.new_numeric_virtual_column = b.numeric_column;の内部結合bからxを選択するように単純化できます。 ' – Boneist
さて、それはアイデアです!私は仮想列を考慮しなかったことを認めなければならない!提案していただきありがとうございます! – 0909EM