[BUG]: Metricas retornam resultados incorretos em alguns joins
Embora o mecanismo funcione corretamente o resultado não é o esperado. O problema ocorre quando a junção das tabelas não é "perfeita". Um exemplo uma view tem os atributos met:count:point e dim:point e outra tem met:sum:download, dim:point, dim:macAddr. A consulta seleciona as duas métricas, logo será feita uam junção das duas views pela dimensão dim:point que é comum entre os dois. Porém o resultado da métrica met:count:point possivelmente será incorreto.
Isso ocorre pois é muito provavel que a segunda tabela que tem mais dimensões tenha mais de uma entrada por dim:point, dessa forma ao realizar o join as entradas da primeira serão repeditas e contabilizadas mais de uma vez, resultando em um resultado incorreto.
Proposta: para realizar joins as views tem que ter uma relação de um para um, ou seja, as mesmas dimensões antes de fazer um join.
Problemas: Em alguns casos é necessário fazer junções com quantidades de dimensões diferentes.
Considere o mesmo exemplo, agora além das métricas a dim:macAddr também é selecionada, a junção com quantidade diferente de dimensões é obrigatória.
Proposta: Em certos casos, a partir de um ponto as métricas devem se comportar como dimensões.
A junção com outra view com quantidade de entradas maior é inevitavel, porém se met:count:point fosse uma dimensão o resultado não seria incorreto, em outras palavras se o valor fosse agrupado ao invés de agregado não seriam contabilizadas de forma errada, logo se comportária como uma dimensão.
Proposta:
- Agregamos as views materializadas separadamente, com as respectivas dimensões necessárias
- Depois da agregação é feito o join, com as dimensões restantes, que seriam as necessárias para realizar o join entre as views e as que foram escolhidas na consulta
- Remoção das dimensões extras (usadas apenas para propósito de junção) agrupando por todos os parametros que estavam na consulta
Problemas:
- Nem todas as views criadas podem ser reaproveitas para realizar outras consultas, e portanto essas não podem ser materializadas.
- A partir do momento que um métrica tem que ser tratada como uma dimensão, ela pode ser replicada e não pode ser agregada novamente
Usando esse algoritmo a query 1 (apenas as métricas) não funcionaria, na realidade ela seria equivalente a consulta utilizando também a dim:point, para que o resultado fosse correto, as métricas teriam que ser agregadas novamente, não tratadas como dimensões, isso se deve ao fato de que a junção nesse caso poderia ter sido "perfeita", primeiro agrupando por dim:point seriam criadas views com dimensões iguais, assim elas poderiam ser juntadas normalmente e as metricas poderiam ser agregadas normalmente.
Solução:
As junções devem ser feitas 2 a 2, ao invés de todas ao mesmo tempo, em formato de árvore, sempre que uma junção "perfeita" foi feita em um passo, então o resultado deve ser agregado novamente removendo as dimensões de junção, se for o caso. Se a junção não for perfeita a partir desse ponto as métricas devem ser tratadas como dimensões.
- Escolhe-se 2 views
- Agregamos as views separadamente, com as respectivas dimensões necessárias, tanto para consulta como para joins (além das duas em questão, mas de todo o conjunto)
- Faz-se o join das duas views
- Se a junção foi perfeita, as métricas continuam factíveis e podem continuar sendo agregadas, caso contrário marca as métricas para que sejam tratadas como dimensões agora e a view como não-materializavel
- Volta para o passo 1 até que reste apenas uma view
- Se a última junção foi perfeita agrega a view com as métricas restantes (métricas marcadas para o algoritmo não são consideradas métricas)
Problemas:
- Vão existir views não-materializaveis (Elas podem serr materizalizadas mas seu resultado não pode ser aproveitado por outras consultas, então é pouco desejavel materializar uma consulta dessas)
- Muito provavelmente a consulta construída será muito menos eficiente
- A partir do momento que um métrica tem que ser tratada como uma dimensão, ela pode ser replicada e não pode ser agregada novamente
Resolve: A junção de views com quantidade de dimensões diferentes se torna possível e retorna o resutlado correto