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

COUNT(col)... GROUP BYを取得してインデックスを使用するにはどうすればよいですか?

    私はこれをいじくり回す機会がありました、そして、NOT INに関する私の以前のコメントは、この場合、赤いニシンです。重要なのは、NULLの存在、つまりインデックス付きの列にNOTNULL制約が適用されているかどうかです。

    オプティマイザーはリリースごとにスマートになるため、これは使用しているデータベースのバージョンによって異なります。私は11gR1を使用しており、オプティマイザーは1つを除くすべての場合にインデックスを使用しました。両方の列がnullで、NOT INを含めなかった場合 条項:

    SQL> desc big_table
     Name                                  Null?    Type
     -----------------------------------  ------    -------------------
     ID                                             NUMBER
     COL1                                           NUMBER
     COL2                                           VARCHAR2(30 CHAR)
     COL3                                           DATE
     COL4                                           NUMBER
    

    NOTIN句なし...

    SQL> explain plan for
      2      select col4, count(col1) from big_table
      3      group by col4
      4  /
    
    Explained.
    
    SQL> select * from table(dbms_xplan.display)
      2  /
    
    PLAN_TABLE_OUTPUT
    ---------------------------------------------------------------------------------------
    Plan hash value: 1753714399
    
    ----------------------------------------------------------------------------------------
    | Id  | Operation          | Name      | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |           | 31964 |   280K|       |  7574   (2)| 00:01:31 |
    |   1 |  HASH GROUP BY     |           | 31964 |   280K|    45M|  7574   (2)| 00:01:31 |
    |   2 |   TABLE ACCESS FULL| BIG_TABLE |  2340K|    20M|       |  4284   (1)| 00:00:52 |
    ----------------------------------------------------------------------------------------
    
    9 rows selected.
    
    
    SQL>
    

    NOT INをドブしたとき 条項に戻ると、オプティマイザーはインデックスを使用することを選択しました。奇妙な。

    SQL> explain plan for
      2      select col4, count(col1) from big_table
      3      where col1 not in (12, 19)
      4      group by col4
      5  /
    
    Explained.
    
    SQL> select * from table(dbms_xplan.display)
      2  /
    
    PLAN_TABLE_OUTPUT
    ---------------------------------------------------------------------------------------
    Plan hash value: 343952376
    
    ----------------------------------------------------------------------------------------
    | Id  | Operation             | Name   | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT      |        | 31964 |   280K|       |  5057   (3)| 00:01:01 |
    |   1 |  HASH GROUP BY        |        | 31964 |   280K|    45M|  5057   (3)| 00:01:01 |
    |*  2 |   INDEX FAST FULL SCAN| BIG_I2 |  2340K|    20M|       |  1767   (2)| 00:00:22 |
    ----------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    
    PLAN_TABLE_OUTPUT
    ----------------------------------------------------------------------------------------
    
       2 - filter("COL1"<>12 AND "COL1"<>19)
    
    14 rows selected.
    
    SQL>
    

    繰り返しになりますが、他のすべての場合、インデックス付きの列の1つがnillでないと宣言されている限り、クエリを満たすためにインデックスが使用されました。これは、以前のバージョンのOracleには当てはまらない可能性がありますが、おそらく今後の方向性を示しています。



    1. オラクルでの日付のキャスト

    2. MySQLデータベースからのBLOBイメージの読み取り

    3. SQLServerDBスキーマをMySQLに移植する最良の方法

    4. mysqlにクエリを実行し、PHPでデータをCSVとしてエクスポートします