Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Jak mogę uzyskać COUNT(col)... GROUP BY, aby użyć indeksu?

Miałem okazję się tym pobawić, a moje poprzednie komentarze dotyczące NOT IN są w tym przypadku czerwone. Kluczową rzeczą jest obecność wartości NULL, a raczej to, czy indeksowane kolumny nie mają narzuconych ograniczeń NULL.

Będzie to zależeć od używanej wersji bazy danych, ponieważ optymalizator staje się coraz mądrzejszy z każdym wydaniem. Używam 11gR1 i optymalizator używał indeksu we wszystkich przypadkach z wyjątkiem jednego:gdy obie kolumny miały wartość null i nie uwzględniłem NOT IN klauzula:

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

Bez klauzuli 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>

Kiedy zdobyłem NOT IN z powrotem, optymalizator zdecydował się na użycie indeksu. Dziwne.

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>

Powtórzę, we wszystkich innych przypadkach, o ile jedna z indeksowanych kolumn nie była pusta, indeks był używany do spełnienia zapytania. Może to nie być prawdą we wcześniejszych wersjach Oracle, ale prawdopodobnie wskazuje drogę naprzód.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Załaduj ogromny plik csv do tabeli bazy danych Oracle za pomocą Pyspark

  2. Funkcja Thousand Seperator w wyroczni?

  3. SQLcl do przesyłania danych z Oracle do PostgreSQL lub YugabyteDB 🅾🐘🚀

  4. Oracle SQL:wyodrębnianie tygodnia roku od daty daje losowe wyniki

  5. średnia sprzedaż kwartału z poprzednim kwartałem średnia sprzedaż