Oracle hat eine neue Funktion, Group by Elimination, für Abfragen eingeführt, bei denen die Group by-Spalte auch der eindeutige Schlüssel der Tabelle ist. Wie bei vielen neuen Funktionen wurden auch hier noch nicht alle Probleme gelöst. Das Problem entsteht, wenn Schlüsselwerte mit Funktionsaufrufen manipuliert werden. Das folgende Beispiel veranschaulicht das Problem, indem eine Tabelle mit einem DATE als Primärschlüssel verwendet wird und das Jahr durch Extrahieren mit TO_CHAR oder EXTRACT.
extrahiert wirdEine Tabelle wird wie folgt erstellt:
create table bug_test_calendar( cal_name char(17), bus_dt date, updt_timestamp timestamp (6) default systimestamp, constraint pk_bug_test_calendar primary key (bus_dt) ) / insert into bug_test_calendar (bus_dt) select sysdate + 10 * rownum from all_objects where rownum <= 40 / commit;
Wenn die unten gezeigte Abfrage ausgeführt wird, erzeugt sie die folgenden Ergebnisse:
select to_char(bus_dt,'YYYY') bus_dt, count(*) ct from bug_test_calendar group by to_char(bus_dt,'YYYY') order by to_char(bus_dt,'YYYY') / BUS_DF CT ------- -- 2020 1 2020 1 ... 2020 1 40 rows returned
Oracle „weiß“ nicht, dass die Schlüsselwerte so manipuliert wurden, dass sie nicht mehr eindeutig sind, daher wendet der Optimierer die auf eindeutigen Schlüsseln basierende Group-By-Eliminierung mit weniger als herausragenden Ergebnissen an,
EXTRACT schneidet nicht besser ab und liefert die gleichen Ergebnisse. Dieses Verhalten wird durch den Parameter „_optimizer_aggr_groupby_elim“ gesteuert, der standardmäßig auf „true“ gesetzt ist. Da es sich um einen versteckten Parameter handelt, wird seine Einstellung von Oracle weder in der V$PARAMEter- noch in der V$SPPARAMETER-Ansicht gemeldet. Die Problemumgehung besteht darin, diesen Parameter einfach auf „false“ zu setzen. Die Aktivierung kann jedoch anderen Gruppieren-nach-Abfragen helfen, bei denen die eindeutigen Schlüsselwerte nicht manipuliert werden.
Geben Sie Oracle 19c ein, wo diese Funktionalität teilweise behoben ist:
select to_char(bus_dt,'YYYY') bus_dt, count(*) ct from bug_test_calendar group by to_char(bus_dt,'YYYY') order by to_char(bus_dt,'YYYY') / BUS_DF CT ------- -- 2020 40
Leider ist EXTRACT in 19c immer noch kaputt:
select to_char(bus_dt,'YYYY') bus_dt, count(*) ct from bug_test_calendar group by extract(year deom bus_dt) order by extract(year deom bus_dt) / BUS_DF CT ------- == 2020 1 2020 1 ... 2020 1 40 rows returned
Offensichtlich würde eine Gruppieren-nach-Abfrage bei wirklich eindeutigen Schlüsselwerten eine Zählung von 1 für jeden Schlüssel erzeugen. Und ebenso offensichtlich sollte Oracle in der Lage sein, zu erkennen, wenn Werte nicht mehr eindeutig sind, und den richtigen Group-By-Mechanismus aufzurufen. Es bleibt abzuwarten, ob Versionen nach 19c die zweite Bedingung beheben und somit korrekte Ergebnisse liefern, ohne diese Funktion ausschalten zu müssen.
Dies betrifft möglicherweise nicht jede Installation von Oracle neuer als 12.1, aber es ist wichtig zu wissen, falls falsche Ergebnisse in ausgewählten Gruppen nach Abfragen angezeigt werden.
# # #
Siehe Artikel von David Fitzjarrell