Eu tenho uma tabela grande (dezenas a centenas de milhões de registros) que dividimos por motivos de desempenho em tabelas ativas e de arquivamento, usando um mapeamento de campo direto e executando um processo de arquivamento todas as noites.
Em vários lugares do nosso código, precisamos executar consultas que combinam as tabelas ativas e de arquivamento, quase invariavelmente filtradas por um ou mais campos (nos quais obviamente colocamos índices nas duas tabelas). Por conveniência, faria sentido ter uma visão como esta:
create view vMyTable_Combined as
select * from MyTable_Active
union all
select * from MyTable_Archive
Mas se eu executar uma consulta como
select * from vMyTable_Combined where IndexedField = @val
ele fará a união em tudo, desde Active e Store antes de filtrar @val
, o que prejudicará o desempenho.
Existe alguma maneira inteligente de fazer com que as duas subconsultas da união visualizem cada filtro @val
antes de criar a união?
Ou talvez exista alguma outra abordagem que você sugerir que atinja o que pretendo, ou seja, uma maneira fácil e eficiente de obter o conjunto de registros da união, filtrado pelo campo indexado?
EDIT: aqui está o plano de execução (e você pode ver os nomes das tabelas reais aqui):
Curiosamente, a tabela ativa está realmente usando o índice correto (mais uma pesquisa de RID?), Mas a tabela de arquivamento está fazendo uma varredura de tabela!
fonte
Respostas:
Os comentários sobre a pergunta mostram que o problema é que o banco de dados de teste que o OP estava usando para desenvolver a consulta tinha características de dados radicalmente diferentes do banco de dados de produção. Tinha muito menos linhas e o campo usado para filtragem não era seletivo o suficiente.
Quando o número de valores distintos em uma coluna é muito pequeno, o índice pode não ser suficientemente seletivo. Nesse caso, uma varredura seqüencial de tabela é mais barata que uma operação de busca de índice / linha. Normalmente, uma varredura de tabela faz uso extensivo de E / S seqüencial, o que é muito mais rápido do que as leituras de acesso aleatório.
Frequentemente, se uma consulta retornar mais do que apenas alguns por cento das linhas, será mais barato fazer uma varredura de tabela do que uma pesquisa de índice / pesquisa de linha ou operação semelhante que faça uso pesado de E / S aleatória.
fonte
Só para adicionar, o que eu encontrei. Se você fizer:
Em seguida, você pode filtrar no campo [Ativo] e garantir que a outra parte não esteja carregada.
fonte