Oracle introducerade en ny funktion, grupp för eliminering, för frågor där grupp för kolumn också är tabellens unika nyckel. Som med många nya funktioner har den här fortfarande inte fått alla problem lösta. Problemet uppstår när nyckelvärden manipuleras med funktionsanrop. Följande exempel illustrerar problemet genom att använda en tabell med DATE som primärnyckel och genom att extrahera årtalet extraheras med TO_CHAR eller EXTRACT.
En tabell skapas enligt följande:
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;
När frågan som visas nedan exekveras ger den följande resultat:
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 "vet" inte att nyckelvärdena har manipulerats så att de inte längre är unika, därför tillämpar optimeraren den unika nyckel-baserade grupp-för-elimineringen med mindre än fantastiska resultat,
EXTRAKT blir inte bättre, och ger samma resultat. Detta beteende styrs av parametern "_optimizer_aggr_groupby_elim", som är satt till sant som standard. Eftersom det är en dold parameter, rapporteras inte dess inställning av Oracle i någon av V$PARAMEter- eller V$SPPARAMETER-vyerna. Lösningen är att helt enkelt ställa in den här parametern till false. Men att ha den aktiv kan hjälpa andra gruppvisa frågor där de unika nyckelvärdena inte manipuleras.
Gå in i Oracle 19c, där denna funktion är delvis fixad:
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
Tyvärr är EXTRACT fortfarande trasigt i 19c:
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
Givet verkligt unika nyckelvärden skulle en gruppvis fråga uppenbarligen producera ett antal 1 för varje nyckel. Och, lika självklart, borde Oracle kunna känna igen när värden inte längre är unika och åberopa rätt gruppvis mekanism. Det återstår att se om versioner efter 19c kommer att fixa det andra villkoret och därmed returnera korrekta resultat utan att behöva stänga av den här funktionen.
Detta kanske inte påverkar alla installationer av Oracle som är nyare än 12.1, men det är värt att veta om fel resultat börjar dyka upp i den valda gruppen efter frågor.
# # #
Se artiklar avDavid Fitzjarrell