Isso é resultado dessa pergunta .
Então, estou trabalhando com uma consulta que se parece com isso:
select count(*)
from table1
where col1 = 123
and col2 = '1';
O problema é este: col2
é definido como um CHAR(1)
e todas as sessões definidas NLS_SORT = 'BINARY_CI'
e NLS_COMP = 'LINGUISTIC'
. ( col1
é uma NUMBER
coluna.)
Em primeiro lugar, sem as configurações de NLS ativadas para as sessões, definir uma estatística estendida de várias colunas (col1,col2)
funciona bem e produz cardinalidade apropriada.
Mas com NLS_SORT = 'BINARY_CI'
e NLS_COMP = 'LINGUISTIC'
, ele não usa as estatísticas estendidas. Achei muito parecido com um índice e as configurações do NLS - tivemos que definir índices com (NLSSORT("COL2",'nls_sort=''BINARY_CI'''))
.
Então, implementei estatísticas estendidas de várias colunas em ("COL1", (NLSSORT("COL2",'nls_sort=''BINARY_CI'''))
. Mas ainda não funciona (mas um índice definido da mesma forma funcionará).
Nas informações do predicado, mostra que com as configurações do NLS ativadas, col2 = '1'
é transformado em:
NLSSORT(INTERNAL_FUNCTION(col2),'nls_sort=''BINARY_CI''')=HEXTORAW('3100')
. Eu acredito que o INTERNAL_FUNCTION()
é devido a col2
ser definido como CHAR(1)
. Eu não posso mudar isso.
Como posso criar um grupo de colunas estatísticas estendidas de várias colunas para essas colunas, dadas minhas condições?
Acho que sua única opção aqui é 'rolar suas próprias' estatísticas pseudo-multicolunas - já que estatísticas estendidas não podem ser criadas em colunas virtuais . Por exemplo:
banco de ensaio:
primeiro tente com histogramas normais (observe que a estimativa de 'linhas' é 'ruim'):
agora crie uma coluna virtual concatenada (observe que a estimativa de 'linhas' é 'boa'):
finalmente, repita com os parâmetros NLS definidos:
sem índice:
com índice: