Eu tenho uma tabela de origem que se parece essencialmente com isso:
- Código de empregado
- Data de início da semana
- Horas Trabalhadas Dia1
- Horas Trabalhadas Dia2
- Horas Trabalhadas Dia3
- Horas Trabalhadas Dia 4
- Horas Trabalhadas Dia5
- Horas TrabalhadasDia6
- Horas TrabalhadasDia7
A tabela real tem algo como 500 colunas numeradas (na verdade não as contei - existem vários e numerosos campos numerados de 1 a 7 e, em seguida, outro punhado numerado de 1 a 25, vezes 7) por dia da semana (não, esse não é o meu projeto) , e atualmente há algo como 38.600 linhas (crescendo a cada semana).
Eu tenho um pacote SSIS que está tentando normalizar esses dados... que atualmente se parece com isso:
Cada "origem" está selecionando um conjunto de colunas numeradas da mesma tabela de origem, e o componente UNION ALL combina as 7 origens em uma, resultando em cerca de 258.900 linhas.
O restante do fluxo de trabalho adiciona algumas colunas calculadas, procura chaves substitutas (por exemplo EmployeeCode
, é usado para pesquisar um EmployeeId
, e então a data é calculada e usada para procurar um TimeId
) e, em seguida, as linhas "modificadas" são atualizadas e as "novas" uns são inseridos em uma tabela normalizada; linhas inalteradas não terminam em lugar nenhum.
Existe alguma maneira melhor (por exemplo, um pouco menos pesado na pressão da memória) para normalizar os dados de origem?
Sem a definição completa da tabela, é difícil fornecer uma resposta perfeita. Porém, na tentativa de mostrar as diferenças em uma reprodução limitada, com uma quantidade muito pequena de dados, criei o seguinte testbed:
Abaixo estamos comparando as duas consultas; o primeiro usa o
CROSS APPLY
método, detalhado por mim em SQLServerScience.com , e o segundo usa oUNION ALL
método.Primeira coisa a notar,
CROSS APPLY
é mais fácil de olhar. Isso já me deixa feliz.Vamos verificar os planos de execução para as duas variantes:
A
UNION ALL
variante verifica a tabela de origem 7 vezes, enquanto a varianteCROSS APPLY
usa uma única verificação de tabela. Ao usar a aplicação cruzada, estamos #Vencendo.Vamos adicionar mais dados:
No meu sistema, o código acima gerou cerca de 85.000 linhas. Os planos para as duas consultas agora são:
O SQL Sentry Plan Explorer mostra as seguintes informações resumidas, que são inestimáveis:
Isso diz que a CPU é usada mais intensamente pelo
CROSS APPLY
, porém há 7 vezes mais I/O usado pelaUNION ALL
variante.