Estou procurando maneiras de melhorar o desempenho do meu banco de dados para consultas analíticas pesadas e descobri que meu espaço de tabela temporário tem extensões de 1 milhão (padrão para espaço de tabela uniforme). Com meu uso normal de espaço de tabela temporário muito acima de 1 GB por consulta (as principais consultas com junções/classificações/grupos pesados podem consumir até 100 GB de espaço de tabela temporário), extensões de 1 milhão parecem muito baixas para mim. Vale a pena aumentar o tamanho da extensão para desempenho?
Andy DB Analyst's questions
Temos uma grande variedade de tabelas particionadas por mês. Estatísticas incrementais ativadas. Após a coleta programada de estatísticas, a estimativa de cardinalidade torna-se estranha, como
select count(*) from my_table where date >= trunc(sysdate) - 30 and date < trunc(sysdate)
fornece 1,3 milhão de linhas, mas a estimativa é de 20 mil. Somente depois de reunir manualmente as estatísticas, a estimativa se torna precisa. Exemplos de código:
-- Scheduled
dbms_stats.gather_table_stats
(
ownname=> 'ownname',
tabname=> 'tabname' ,
estimate_percent=> DBMS_STATS.AUTO_SAMPLE_SIZE,
cascade=> DBMS_STATS.AUTO_CASCADE,
degree=> 4,
no_invalidate=> DBMS_STATS.AUTO_INVALIDATE,
granularity=> 'AUTO',
method_opt=> 'FOR ALL COLUMNS SIZE AUTO'
);
-- Manual
DBMS_STATS.GATHER_TABLE_STATS
(
ownname => '"ownname"',
tabname => '"tabname"',
partname => '"partname"',
method_opt => 'FOR COLUMNS DATE SIZE 254',
estimate_percent => 1
);
Outras tabelas particionadas estão ok.
As diferenças entre esta tabela e outras são (como sabemos):
- Havia inserções erradas nesta tabela. A maioria das datas está entre 2014 e 2023, mas há algumas linhas com 1970 e 2024 (não podemos alterá-las). Também há uma partição vazia com 2045. Tentamos recriar isso, mas não obtivemos o mesmo comportamento.
- Mexemos nos histogramas, removemos alguns criados automaticamente e criamos manualmente alguns úteis baseados em funções. Mas em USER_TAB_COL_STATISTICS e USER_TAB_HISTOGRAMS os histogramas para a coluna DATE estavam presentes.
O que pode causar tal comportamento? Como podemos arranjá-lo?
Ao tentar classificar alguns valores hexadecimais, obtive resultados diferentes para agregação MAX() e classificação ORDER BY desc:
with some_data as
(
select '123A55' as hex
from dual
union all
select '123255' as hex
from dual
)
select max(hex)
from some_data
;
Result: 123A55
with some_data as
(
select '123A55' as hex
from dual
union all
select '123255' as hex
from dual
)
select *
from some_data
order by hex desc
;
Result:
123255
123A55
No banco de dados MySQL dá 123A55 em ambos os casos.
Existem regras diferentes no ORACLE para ordem de classificação para MAX() MIN() e ORDER BY?