SQL CASE NÅR <verdi> i sakte på SQL Server 2005, men ikke 2000

stemmer
2

Jeg har en veldig enkel spørring som driver meg helt gal.

Her er situasjonen:

  • Jeg har to databaseservere.
  • Den ene er en gammel SQL Server 2000 (VM), svært minimale ressurser.
  • Den andre er en veldig stor SQL Server 2005 Enterprise klynge med en helt latterlig mengde ressurser tilgjengelig.
  • Jeg har en liten del av et større spørring som utfører i 3 sekunder og returnerer 50.000 rader med data på SQL Server 2000
  • Den samme lille spørringen tar i overkant av 15 minutter for å gå tilbake 1000 rader på SQL Server 2005
  • Databasen jeg jobber med er et speilbilde på følgende to servere. Samme bord, samme dataene i tabeller, samme indeksene på tabeller, etc.

Jeg har prøvd å lage ulike indekser på SQL Server 2005 tabeller, defragged alle indeksene som finnes, oppdaterte tabellstatistikk, etc. Ingenting har vært i stand til å gjøre dette søket kjøre raskere på SQL Server 2005. Foreløpig ingenting annet kjører mot SQL server 2005 server, og våre DBA forsikre meg om det ikke er et konfigurasjonsproblem eller noe å gjøre med funksjonen avskrivninger mellom SQL server 2000 og SQL server 2005.

Spørringen er under:

SELECT (CASE 
             WHEN TeamMember.ID IN  (SELECT DISTINCT ProjMgrID FROM ProjMgr)
                THEN 'Yes' 
                ELSE 'No' 
        END) AS OnProjAsMgr 
FROM TeamMember

Så tilbake en tydelig oversikt over alle ProjMgrs, og hvis TeamMember er på den listen deretter tildele Ja til OnProjAsMgr verdi.

Jeg er en total SQL nybegynner, og dette er kode skrevet av en forgjenger. Jeg vet ikke om det er en bedre måte å skrive det, men jeg kan ikke finne ut hvorfor det går bra på SQL Server 2000, men helt implodes på SQL Server 2005.

Publisert på 11/09/2012 klokken 20:31
kilden bruker
På andre språk...                            


3 svar

stemmer
5

DISTINCT fører til en slags, og får hele spørringen som skal evalueres. Hvordan fungerer denne versjonen arbeid:

SELECT OnProjAsMgr = CASE WHEN EXISTS 
  (SELECT 1 FROM dbo.ProjMgr WHERE ProjMgrID = TeamMember.ID)
  THEN 'Yes' 
  ELSE 'No' 
  END
FROM dbo.TeamMember;

Hvis denne fares ikke bedre da jeg mistenker indekser mangler og ingen spørring vil gi gode resultater uten dem.

Svarte 11/09/2012 kl. 20:38
kilden bruker

stemmer
1

Jeg vet ikke om "bedre" måte, men her er en annen måte som du kan prøve:

SELECT ... other fields you want ...,
       CASE WHEN ProjMgr.ProjMgrID IS NULL
            THEN 'No'
            ELSE 'Yes'
        END AS OnProjAsMgr
  FROM TeamMember
  LEFT
 OUTER
  JOIN ProjMgr
    ON ProjMgr.ProjMgrID = TeamMember.ID
;

Merknader:

  • På noen DBMSes, vil denne utføre mye bedre enn søket, men jeg vet ikke om det ville gi bedre resultater på SQL Server 2005, gitt at søket allerede fungerer fint på SQL Server 2000. Jeg tror du bare må prøve den.
  • Søket bruker SELECT DISTINCT ProjMgrID FROM ProjMgr. Hvis det er faktisk forskjellig fra SELECT ProjMgrID FROM ProjMgr- det vil si, hvis det er faktisk like verdier av ProjMgrIDi ProjMgr- da ovennevnte spørsmålet er ikke akkurat lik din, siden det vil gi en egen post for hver duplikat. Du må kanskje legge til en GROUP BYklausul i så fall.
  • For den saks skyld, hvis SELECT DISTINCT ProjMgrID FROM ProjMgrtilsvarer SELECT ProjMgrID FROM ProjMgrfor dine data, som jeg mistenker, så er det også kan være verdt å fjerne DISTINCT, siden det kan påvirke optimizer også.
Svarte 11/09/2012 kl. 20:38
kilden bruker

stemmer
-1
SELECT (
    CASE WHEN P.ID IS NULL THEN 'No' ELSE 'Yes' END
) AS OnProjAsMgr
FROM TeamMember AS T 
LEFT OUTER JOIN ProjMgr AS P ON T.ID=P.ID
Svarte 11/09/2012 kl. 20:41
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more