Oracle
 sql >> Database >  >> RDS >> Oracle

Uno sguardo al bug di Oracle Group-by

Oracle ha introdotto una nuova funzionalità, raggruppamento per eliminazione, per le query in cui il gruppo per colonna è anche la chiave univoca della tabella. Come per molte nuove funzionalità, questa non ha ancora risolto tutti i nodi. Il problema sorge quando i valori chiave vengono manipolati con chiamate di funzione. L'esempio seguente illustrerà il problema utilizzando una tabella con una DATE come chiave primaria ed estraendo l'anno viene estratto utilizzando TO_CHAR o EXTRACT.

Viene creata una tabella come segue:

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;

Quando viene eseguita la query mostrata di seguito, produce i seguenti risultati:

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 non "sa" che i valori chiave sono stati manipolati in modo che non siano più univoci, quindi l'ottimizzatore applica l'eliminazione group-by basata su chiavi univoche con risultati non eccezionali,

EXTRACT non va meglio, restituendo gli stessi risultati. Questo comportamento è controllato dal parametro "_optimizer_aggr_groupby_elim", che è impostato su true per impostazione predefinita. Poiché si tratta di un parametro nascosto, la sua impostazione non viene riportata da Oracle in nessuna delle viste V$PARAMEter o V$SPPARAMETER. La soluzione alternativa è semplicemente impostare questo parametro su false. Tuttavia, averlo attivo potrebbe aiutare altre query raggruppate in cui i valori chiave univoci non vengono manipolati.

Immettere Oracle 19c, dove questa funzionalità è parzialmente corretta:

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


Sfortunatamente EXTRACT è ancora rotto in 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

Ovviamente dati valori chiave veramente unici, una query raggruppata produrrebbe un conteggio di 1 per ogni chiave. E, altrettanto ovvio, Oracle dovrebbe essere in grado di riconoscere quando i valori non sono più univoci e invocare il corretto meccanismo di raggruppamento. Resta da vedere se le versioni successive alla 19c risolveranno la seconda condizione e quindi restituiranno risultati corretti senza dover disattivare questa funzione.

Ciò potrebbe non influire su tutte le installazioni di Oracle successive alla 12.1, ma vale la pena sapere se i risultati errati iniziano a comparire nel gruppo selezionato per query.

# # #

Vedi gli articoli di David Fitzjarrell