ALguém poderia dar um help, eu tenho a seguinte consulta SELECT DISTINCT
PRJ_Projetos.PRJ_Descricao AS [Nome do Projeto], USR_Usuarios.USR_Nome AS Usuário, PHS_PlanilhaHoras.PHS_Data AS Data,
PHS_PlanilhaHoras.PHS_Fim - PHS_PlanilhaHoras.PHS_Inicio AS [Total de Horas]
FROM PHS_PlanilhaHoras CROSS JOIN
PRJ_Projetos CROSS JOIN
TOP_Topicos CROSS JOIN
USR_Usuarios CROSS JOIN
VER_Versoes
WHERE (PHS_PlanilhaHoras.PHS_Data BETWEEN @Periodo_Ini AND @Periodo_Fim) AND (PRJ_Projetos.PRJ_Descricao LIKE '%' + @Projeto + '%') AND
(VER_Versoes.VER_Descricao LIKE '%' + @Versao + '%') AND (TOP_Topicos.TOP_Observacoes LIKE '%' + @Topico + '%')
ORDER BY USR_Usuarios.USR_Nome, PRJ_Projetos.PRJ_Descricao, PHS_PlanilhaHoras.PHS_Data
Mas é gerado muito dados, caso o periodo ultrapasse 1 ano a consulta leva mais de 2 minutos para completar, ha alguma maneira melhor de se fazer ?
[quote=zopo]ALguém poderia dar um help, eu tenho a seguinte consulta SELECT DISTINCT
PRJ_Projetos.PRJ_Descricao AS [Nome do Projeto], USR_Usuarios.USR_Nome AS Usuário, PHS_PlanilhaHoras.PHS_Data AS Data,
PHS_PlanilhaHoras.PHS_Fim - PHS_PlanilhaHoras.PHS_Inicio AS [Total de Horas]
FROM PHS_PlanilhaHoras CROSS JOIN
PRJ_Projetos CROSS JOIN
TOP_Topicos CROSS JOIN
USR_Usuarios CROSS JOIN
VER_Versoes
WHERE (PHS_PlanilhaHoras.PHS_Data BETWEEN @Periodo_Ini AND @Periodo_Fim) AND (PRJ_Projetos.PRJ_Descricao LIKE '%' + @Projeto + '%') AND
(VER_Versoes.VER_Descricao LIKE '%' + @Versao + '%') AND (TOP_Topicos.TOP_Observacoes LIKE '%' + @Topico + '%')
ORDER BY USR_Usuarios.USR_Nome, PRJ_Projetos.PRJ_Descricao, PHS_PlanilhaHoras.PHS_Data
Mas é gerado muito dados, caso o periodo ultrapasse 1 ano a consulta leva mais de 2 minutos para completar, ha alguma maneira melhor de se fazer ?
Obrigado[/quote]
Como está o relacionamento entre as tabelas??
Specifies the cross-product of two tables. Returns the same rows as if the tables to be joined were simply listed in the FROM clause and no WHERE clause was specified. For example, both of these queries return a result set that is a cross join of all the rows in T1 and T2:
SELECT * FROM T1, T2
SELECT * FROM T1 CROSS JOIN T2
Para ficar compatível com outros bancos, simplesmente liste as tabelas, em vez de usar CROSS JOIN. É que isso confunde um monte de gente (só de ver um CROSS JOIN as pessoas já pensam em produto cartesiano, que é o que você não está pensando em fazer.)
PHS_PlanilhaHoras PHS,
PRJ_Projetos PRJ,
TOP_Topicos TOP,
USR_Usuarios USR,
VER_Versoes VER
Se puder eliminar o “%” do lado esquerdo do LIKE, pode ser que o SQL ache um índice adequado e evite percorrer TODA a tabela.
PRJ_Projetos.PRJ_Descricao LIKE @Projeto + '%'
pode usar um índice sobre “PRJ_DESCRICAO” que eliminaria a consulta a milhares de linhas de sua tabela.
Além disso, como você mesmo notou, a sua consulta deve ter um erro (não está levando em conta os relacionamentos entre as tabelas), porque volta dados demais.
Mas é exatamente isso que o CROSS JOIN faz :?
A cláusula ANSI para join entre tabelas sem especificar as colunas é o NATURAL JOIN. CROSS JOIN sempre gera plano cartesiano.
ex:select t.descricao, p.preco
from produto p natural join tipoproduto t
igual a
select t.descricao, p.preco
from produto p, tipoproduto t
p.codtipoproduto = t.codtipoproduto
Quer uma dica? Gere o plano de execução dessa query e mande o RDBMS gerar dados de profilling também. Com isso você pode descobrir como fazer o tunning dela.