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

OracleにOR接続された述語をUNIONALL操作に変換させます

    これは、ORで使用する列に存在するインデックスと関係があると思います 述語。

    11gR2で以下を使用してテストしました。

    create table scott.test as 
    select level l, 
           decode(mod(level,2), 1, 1, 2) x, 
           decode(mod(level,2), 1, 2, 1) y, 
           dbms_random.value(1, 3) z from dual 
    connect by level < 1000;
    /
    
    begin
       dbms_stats.gather_table_stats('scott', 'test');
    end;
    /
    

    次に、TOADで次のクエリについて説明しました(EXPLAIN PLAN FOR

    select x, y, z from scott.test
        where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
        ;
    
    SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          4                                
      TABLE ACCESS FULL COS_DM.TEST 10      280     4   
    
    select /*+ USE_CONCAT */ x, y, z from scott.test
    where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
    ;
    
    SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          4                                
      TABLE ACCESS FULL COS_DM.TEST 10      280     4                                
    
    
    select x, y, z from test where (floor(z) = 1 and x = 1)
    union all
    select x, y, z from test where (floor(z) = 2 and y = 1)
    ;
    
    SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          8                                
      UNION-ALL                                              
        TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                
        TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                
    

    したがって、ヒントが機能していないようです。次に、x列とy列にインデックスを追加しました:

    create index test_x on test (x, y);
    
    begin
       dbms_stats.gather_table_stats('scott', 'test');
    end;
    /
    

    今すぐクエリを再実行する:

    select x, y, z from scott.test
        where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
        ;
    
    SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          4                                
      TABLE ACCESS FULL COS_DM.TEST 10      280     4   
    
    select /*+ USE_CONCAT */ x, y, z from scott.test
    where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
    ;
    
    SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          8                                
      CONCATENATION                                              
        TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                
        TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                
    
    select x, y, z from test where (floor(z) = 1 and x = 1)
    union all
    select x, y, z from test where (floor(z) = 2 and y = 1)
    ;
    
    SELECT STATEMENT Optimizer Mode=ALL_ROWS        10          8                                
      UNION-ALL                                              
        TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                
        TABLE ACCESS FULL   COS_DM.TEST 5   140     4                                
    

    インデックスを追加した後(使用されていない)、 )オプティマイザーは結局ヒントを使用することにしました!

    おそらくこれを試すことができますか?



    1. PostgresJSONデータ型Railsクエリ

    2. 不正な文字列値:'\ xEF \ xBF\xBD'列

    3. pg_table_size、pg_relation_size、pg_total_relation_sizeの違いは何ですか? (PostgreSQL)

    4. MySQLINクエリで順序を維持する