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