优化SQL查询

VSP*_*VSP 0 sql t-sql

我有一个需要1:20分钟才能执行的sql.它处理一年的数据,但即便如此,我觉得它需要太长时间.我根据另一个查询的建议改变了IN使用EXISTS(在这种情况下,优化不是:S)你有另一个优化它的建议吗?

select gd.descripcion,count(gd.descripcion) as total 
from diagnosticos d,gruposdiagnosticos gd, ServiciosMedicos s, pacientes p,Actos a,historias h 
where p.codigo=h.codpaciente and p.codigo=a.codpaciente and p.codigo=h.codpaciente and p.codigo=s.codpaciente and h.codpaciente=a.codpaciente and h.codpaciente=s.codpaciente and a.codpaciente=s.codpaciente and h.numhistoria=a.numhistoria and h.numhistoria=s.numhistoria and a.numacto=s.numacto and h.codseccion=a.codseccion and a.codseccion=s.codseccion and d.codigo=s.codDiagnostico and gd.codigo=d.codgrupo 
and p.codcompañia ='35' and a.codseccion ='18' 
and (CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) >='20090101') 
and (CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) <='20091231') 
and h.modo ='Urgente' 
and datename(weekday,a.fecatencion)!= 'Sabado' 
and datename(weekday,a.fecatencion)!= 'Domingo' 
AND NOT EXISTS (select * from diasfestivos af where (datename(d,a.fecatencion) + datename(m,a.fecatencion))=(datename(d,af.fechafestiva) + datename(m,af.fechafestiva)) AND CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) >= af.fechafestiva AND CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) < af.fechafestiva + 1 and datepart(yy,af.fechafestiva)='1990') 
AND NOT EXISTS (SELECT * FROM diasfestivos af WHERE CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) >= af.fechafestiva AND CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) < af.fechafestiva + 1 AND datepart(yy,af.fechafestiva)!=1990) 
group by gd.descripcion order by gd.descripcion
Run Code Online (Sandbox Code Playgroud)

使用您的建议更改查询,使其在50秒内完成,谢谢,但应该有一种方法可以减少更多...查询现在是:

select gd.descripcion,count(gd.descripcion) as total 
from diagnosticos d,gruposdiagnosticos gd, ServiciosMedicos s, pacientes p,Actos a,historias h 
where p.codigo=h.codpaciente and p.codigo=a.codpaciente and p.codigo=h.codpaciente and p.codigo=s.codpaciente and h.codpaciente=a.codpaciente and h.codpaciente=s.codpaciente and a.codpaciente=s.codpaciente and h.numhistoria=a.numhistoria and h.numhistoria=s.numhistoria and a.numacto=s.numacto and h.codseccion=a.codseccion and a.codseccion=s.codseccion and d.codigo=s.codDiagnostico and gd.codigo=d.codgrupo 
and p.codcompañia ='35' and a.codseccion ='18' 
and a.fecAtencion +1 >'20090101'
and a.fecAtencion -1 <'20091231' 
and h.modo ='Urgente'  
and DATEPART(dw,a.fecatencion)!=6 
and DATEPART(dw,a.fecatencion)!=7
AND NOT EXISTS (select * from diasfestivos af where (datename(d,a.fecatencion) + datename(m,a.fecatencion))=(datename(d,af.fechafestiva) + datename(m,af.fechafestiva)) AND a.fecAtencion +1 > af.fechafestiva AND a.fecAtencion -1 < af.fechafestiva and datepart(yy,af.fechafestiva)='1990')
AND NOT EXISTS (SELECT * FROM diasfestivos af WHERE a.fecAtencion +1 > af.fechafestiva AND a.fecAtencion -1 < af.fechafestiva AND datepart(yy,af.fechafestiva)!=1990) 
group by gd.descripcion order by gd.descripcion
Run Code Online (Sandbox Code Playgroud)

我有2个存在的部分,因为我有两种类型的节日日期.特别是今年和其他申请每年的人(所以我插入它们像25/12/1990)

最后我发现了问题..这一部分:

其中datename(d,a.fecatencion)+ datename(m,a.fecatencion))=(datename(d,af.fechafestiva)+ datename(m,af.fechafestiva))

有人知道更好的方法吗?(比较tsql省略年份的2个日期时间)

Pen*_*m10 6

  • 使用索引
  • 重写强制转换以使用简单比较可能的between ... and语法
  • 使用数字比较 datename(weekday,a.fecatencion)!= 'Sabado'
  • 您可能可以删除该Actos a表,并用h.codseccion = '18'替换a.codseccion ='18'
  • 您可能可以删除该diagnosticos d表,因为我没有看到任何引用它
  • 您可能可以删除该ServiciosMedicos s表,因为我没有看到任何引用它
  • 总而言之,我发现你有很多连接,并且你没有使用所有的表,删除不必要的连接
  • 重写你的最后两个子查询至少使用 union all例如:( select*from)table union all(select*from),那么至少你会有一次运行而不是两次