sql >> データベース >  >> RDS >> Oracle

SYS_OP_C2C内部変換によるOracleSQL実行プランの変更

    SYS_OP_C2C internal functionです implicit conversionを実行します varchar2national character setTO_NCHARを使用する 関数。したがって、通常の比較を使用したフィルターと比較して、フィルターは完全に変化します。

    行数が少ない理由がわかりません 、しかし私はそれがもっとである可能性があることを保証することができます それも。コスト見積もりは影響を受けません。

    テストケースで段階的に見てみましょう。

    SQL> CREATE TABLE t AS SELECT 'a'||LEVEL col FROM dual CONNECT BY LEVEL < 1000;
    
    Table created.
    
    SQL>
    SQL> EXPLAIN PLAN FOR SELECT * FROM t WHERE col = 'a10';
    
    Explained.
    
    SQL> SELECT * FROM TABLE(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    ----------------------------------------------------------------------------------------------------
    Plan hash value: 1601196873
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |     1 |     5 |     3   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| T    |     1 |     5 |     3   (0)| 00:00:01 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
    PLAN_TABLE_OUTPUT
    ----------------------------------------------------------------------------------------------------
    
       1 - filter("COL"='a10')
    
    13 rows selected.
    
    SQL>
    

    ここまでは順調ですね。値が「a10」の行は1つしかないため、オプティマイザーは1行を推定しました。

    国の文字セット変換で見てみましょう。

    SQL> EXPLAIN PLAN FOR SELECT * FROM t WHERE col = N'a10';
    
    Explained.
    
    SQL> SELECT * FROM TABLE(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    ----------------------------------------------------------------------------------------------------
    Plan hash value: 1601196873
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |    10 |    50 |     3   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| T    |    10 |    50 |     3   (0)| 00:00:01 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
    PLAN_TABLE_OUTPUT
    ----------------------------------------------------------------------------------------------------
    
       1 - filter(SYS_OP_C2C("COL")=U'a10')
    
    13 rows selected.
    
    SQL>
    

    ここで何が起こったのですか? filter(SYS_OP_C2C("COL")=U'a10')が表示されます 、これは、内部関数が適用され、varchar2を変換することを意味します nvarchar2への値 。フィルタで10行が見つかりました。

    これにより、関数が列に適用されるため、インデックスの使用も抑制されます。 function-based indexを作成することで調整できます full table scanを回避するため 。

    SQL> create index nchar_indx on t(to_nchar(col));
    
    Index created.
    
    SQL>
    SQL> EXPLAIN PLAN FOR SELECT * FROM t WHERE to_nchar(col) = N'a10';
    
    Explained.
    
    SQL> SELECT * FROM TABLE(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    ----------------------------------------------------------------------------------------------------
    Plan hash value: 1400144832
    
    --------------------------------------------------------------------------------------------------
    | Id  | Operation                           | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                    |            |    10 |    50 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T          |    10 |    50 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN                  | NCHAR_INDX |     4 |       |     1   (0)| 00:00:01 |
    --------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    
    PLAN_TABLE_OUTPUT
    ----------------------------------------------------------------------------------------------------
    ---------------------------------------------------
    
       2 - access(SYS_OP_C2C("COL")=U'a10')
    
    14 rows selected.
    
    SQL>
    

    ただし、これにより実行プランは類似したものになりますか?いいえ。2つの異なるキャラクターセットで考えます 、フィルターは同様に適用されません。したがって、違いがあります。

    私の調査によると



    1. PL / SQL、文字列内の一重引用符をエスケープする方法は?

    2. MySQLはそのファイルが存在することを確認できますか?

    3. ADFS 2.0を使用して、SQL Serverに対して特定のユーザーを認証できますか?

    4. mysqlクエリ結果をCSVに変換します(コピー/貼り付けあり)