Oracle
 sql >> база данни >  >> RDS >> Oracle

Как мога да получа COUNT(col) ... GROUP BY, за да използвам индекс?

Имах възможността да си поиграя с това и моите предишни коментари относно НЕВХОДЯТ са червена херинга в този случай. Ключовото нещо е наличието на NULL, или по-скоро дали индексираните колони имат наложени НЕ NULL ограничения.

Това ще зависи от версията на базата данни, която използвате, тъй като оптимизаторът става по-умен с всяка версия. Използвам 11gR1 и оптимизаторът използва индекса във всички случаи с изключение на един:когато и двете колони бяха нулеви и не включих NOT IN клауза:

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

Без клаузата NOT IN...

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>

Само да повторя, във всички останали случаи, стига една от индексираните колони да е обявена за ненулева, индексът е използван за удовлетворяване на заявката. Това може да не е вярно за по-ранните версии на Oracle, но вероятно сочи пътя напред.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Променливата на таблицата се попълва само с една стойност

  2. Извличане на XML елементи от XMLType Oracle

  3. Как да издигна изключение в PL/SQL?

  4. Навигирайте от приложение A до приложение B със същите идентификационни данни - APEX 19.2

  5. Каква е разликата между основни, уникални и чужди ключови ограничения и индекси?