2

I have a sql that takes 7 min to execute. It processes a year of data but even so i feel it takes too long. Do you have any suggerences to optimize it?

select count(s.numserviciomedico) AS total 
from Actos a,
    pacientes p,
    Historias h,
    serviciosmedicos s 
where p.codigo=h.codpaciente 
    AND p.codigo=a.codPaciente 
    AND p.codigo = s.codPaciente 
    AND h.codPaciente = a.codPaciente 
    AND a.codpaciente=s.codPaciente 
    AND h.numHistoria = a.numHistoria 
    AND h.numHistoria = s.numHistoria 
    AND a.numHistoria = s.numHistoria 
    AND a.numActo = s.numActo 
    AND h.codSeccion=a.codSeccion 
    and p.codcompañia ='38' 
    and a.codseccion ='9' 
    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 CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) NOT IN (
        select fechafestiva   
        from diasfestivos
    )
5
  • 1
    Have you looked at the execution plan yet? Commented Jan 29, 2010 at 8:21
  • Pleas use some proper code formatting, both in your projects as on SO and other forums. E.g. like I just did Commented Jan 29, 2010 at 8:27
  • Testing i have seen the problem relays in this part: and CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) NOT IN (select fechafestiva from diasfestivos) If i comment it the query executes in 1 sec... Commented Jan 29, 2010 at 9:38
  • The CAST(FLOOR thing its a trick to remove the hour minute part of the datetime...otherwise 2008-03-18 16:19:10.000 != 20080318 If somebody know an optimal way i would be thankful Commented Jan 29, 2010 at 9:50
  • And sorry for the bad formatting i didnt see any tags for code regions... Commented Jan 29, 2010 at 9:51

2 Answers 2

2

At least...

Change this

and (CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) >='20090101') and (CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) <='20091231') 

to

a.fecAtencion >= '20090101' AND a.fecAtencion < '20100101

And use "JOIN"

And

CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) NOT IN (select fechafestiva from diasfestivos)

..to be

NOT EXISTS (SELECT * FROM diasfestivos af WHERE a.fecAtencion >= af.fechafestiva  AND a.fecAtencion < af.fechafestiva + 1)

This assumes diasfestivos has less rows and it's cheaper to remove time there

Sign up to request clarification or add additional context in comments.

Comments

1

The SQL keyword 'IN' is usually a good candidate to replace.

AND NOT EXISTS (select fechafestiva from diasfestivos where CAST(FLOOR(CAST(a.fecAtencion AS float)) AS datetime) = fechafestiva )

And what's up with the datetime casting?

1 Comment

Using this change took a little more time than the original 7:28 min

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.