LIKEパターンマッチング条件 文字タイプが左側と右側の両方のオペランドとして表示されることを期待しています。 NUMBERに遭遇すると、暗黙的にcharに変換します。クエリ1は、基本的にサイレントに次のように書き直されます。
SELECT a1.*
FROM people a1
WHERE TO_CHAR(a1.id) LIKE '119%'
AND ROWNUM < 5
それはあなたの場合に起こります、そしてそれは2つの理由で悪いです:
- 変換はすべての行に対して実行されますが、時間がかかります。
- WHERE述語の関数(暗黙的ではありますが)のため、Oracleは
A1.ID
のインデックスを使用できません。 列。
これを回避するには、次のいずれかを実行する必要があります。
-
関数ベースのインデックス を作成します
A1.ID
に 列:CREATE INDEX people_idx5 ON people (TO_CHAR(id));
-
ID列の最初の3文字のレコードを照合する必要がある場合は、これらの3文字だけを含むタイプNUMBERの別の列を作成し、プレーンな =を使用します。 その上の演算子。
-
別のを作成します 列
ID_CHAR
タイプVARCHAR2
TO_CHAR(id)
で入力します 。インデックスを付けて、ID
の代わりに使用しますWHERE
状態。もちろん、既存のID列に基づいて追加の列を作成する場合は、これら2つの同期を維持する必要があります。これは、単一のUPDATEとして、またはON-UPDATEトリガーでバッチで行うか、その列を適切なものに追加できます。コード内のINSERTステートメントとUPDATEステートメント。