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

Spojrzenie na Oracle Group-by Bug

Oracle wprowadziło nową funkcję, grupuj po eliminacji, dla zapytań, w których grupowanie po kolumnie jest również unikalnym kluczem tabeli. Podobnie jak w przypadku wielu nowych funkcji, ta nadal nie została rozwiązana. Problem pojawia się, gdy wartości kluczy są manipulowane za pomocą wywołań funkcji. Poniższy przykład zilustruje problem, używając tabeli z DATĄ jako kluczem podstawowym i wyodrębniając rok jest wyodrębniany za pomocą TO_CHAR lub EXTRACT.

Tabela jest tworzona w następujący sposób:

utwórz tabelę bug_test_calendar( cal_name char(17), bus_dt data, updt_timestamp timestamp (6) domyślny systimestamp, ograniczenie pk_bug_test_calendar klucz podstawowy (bus_dt))/wstaw do bug_test_calendar (bus_dt) wybierz sysdate + 10 * numer wiersza z numeru wiersza all_object 40 /zatwierdź;

Wykonanie zapytania pokazanego poniżej daje następujące wyniki:

wybierz to_char(bus_dt,'YYYY') bus_dt, count(*) ctfrom bug_test_calendargroup by to_char(bus_dt,'YYYY')order by to_char(bus_dt,'YYYY')/BUS_DF CT------- - -2020 12020 1...2020 Zwrócono 140 wierszy

Oracle nie „wie”, że wartości klucza zostały zmanipulowane w taki sposób, że nie są już unikalne, dlatego optymalizator stosuje eliminację grupową opartą na unikalnym kluczu z mniej niż gwiazdowymi wynikami,

EKSTRAKT nie wypada lepiej, zwracając te same wyniki. To zachowanie jest kontrolowane przez parametr „_optimizer_aggr_groupby_elim”, który jest domyślnie ustawiony na true. Ponieważ jest to ukryty parametr, jego ustawienie nie jest zgłaszane przez Oracle w żadnym z widoków V$PARAMEter lub V$SPPARAMETER. Rozwiązaniem jest po prostu ustawienie tego parametru na false. Jednak jego aktywacja może pomóc w innych zapytaniach grupujących, w których unikatowe wartości klucza nie są manipulowane.

Wpisz Oracle 19c, gdzie ta funkcja jest częściowo naprawiona:

wybierz to_char(bus_dt,'YYYY') bus_dt, count(*) ctfrom bug_test_calendargroup by to_char(bus_dt,'YYYY')order by to_char(bus_dt,'YYYY')/BUS_DF CT------- - -2020 40

Niestety WYCIĄG jest nadal zepsuty w 19c:

select to_char(bus_dt,'YYYY') bus_dt, count(*) ctfrom bug_test_calendargroup by extract(year deom bus_dt)order by extract(year deom bus_dt)/BUS_DF CT------- ==2020 12020 1 ...2020 zwrócono 140 wierszy

Oczywiście przy naprawdę unikalnych wartościach kluczy, zapytanie grupujące dałoby liczbę 1 dla każdego klucza. I, co oczywiste, Oracle powinno być w stanie rozpoznać, kiedy wartości nie są już unikalne i wywołać odpowiedni mechanizm grupowania. Okaże się, czy wersje po 19c naprawią drugi warunek, a tym samym zwrócą poprawne wyniki bez konieczności wyłączania tej funkcji.

Może to nie dotyczyć każdej instalacji Oracle nowszej niż 12.1, ale warto wiedzieć o tym, jeśli w wybranej grupie zaczną pojawiać się błędne wyniki zapytań.

# # #

Zobacz artykuły Davida Fitzjarrella


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Równe (=) vs. LIKE dla typu danych daty

  2. Czy „Wybierz” zawsze porządkuje według klucza podstawowego?

  3. Oracle:Importuj plik CSV

  4. Oracle SQL — sumowanie i grupowanie danych według tygodnia

  5. Inżynieria odwrotna modelu danych przy użyciu Oracle SQL Developer