2017-02-13 2 views
0

Update: bearbeitet den Tabellenalias.Optimieren Sie SQL Server 2008 Abfrage

Ich versuche zu finden, ob die folgende Abfrage neu geschrieben werden kann, um die Leistung zu verbessern. Wir haben in letzter Zeit festgestellt, dass sich die Abfrage sehr stark auf die Leistung auswirkt. Person Tabelle hat fast 10 Millionen und Kontakt Tabelle hat fast 17 Millionen Datensätze.

SELECT 
    ID, NAME, DEPARTMENT, 
    CASE 
     WHEN PrimaryContact = 'MOBILE' 
      THEN (SELECT TOP 1 MOBILE 
       FROM CONTACT 
       WHERE ContactType = 'MOBILE' AND CONTACT.PID = PERSON.PID) 
      ELSE (SELECT TOP 1 HOME 
       FROM CONTACT 
       WHERE CONTACTTYPE = 'HOME' AND CONTACT.PID = PERSON.PID), 
FROM 
    PERSON 
WHERE 
    DEPARTMENT = @DEPARTMENT 

Jede Person kann in der Kontakttabelle eine/mehrere Mobile/Home-Telefonnummern haben. Basierend auf dem primären Kontakttyp sollte nur eine Telefonnummer basierend auf dem Typ PrimaryContact abgerufen werden.

Nebenbei planen wir auch die Person Tabelle basierend auf Department zu partitionieren.

Alle Vorschläge zur Verbesserung der Gesamtleistung werden sehr geschätzt.

Dank

+0

Ihre Anfrage ist so weit von syntaktisch korrekt sein, dass es nicht sinnvoll ist. Was ist "DETAILS"? –

+0

Entschuldigung, das ist PERSON.PID anstelle von DETAILS.PID – Sharmi

+0

Haben Sie sich die ** Ausführungspläne ** für diese Abfrage angesehen? Was zeigen sie? Außerdem: Was sind Ihre Tabellenstrukturen und welche Indizes sind bereits vorhanden? –

Antwort

0

Für diese Abfrage:

SELECT p.ID, p.NAME, p.DEPARTMENT, 
     (CASE WHEN p.PrimaryContact = 'MOBILE' 
      THEN (SELECT TOP 1 c.MOBILE 
        FROM CONTACT c 
        WHERE c.ContactType = 'MOBILE' AND c.PID = p.PID 
       ) 
      ELSE (SELECT TOP 1 c.HOME 
        FROM CONTACT c 
        WHERE c.CONTACTTYPE = 'HOME' AND c.PID = p.PID 
     END) 
FROM PERSON p 
WHERE p.DEPARTMENT = @DEPARTMENT; 

Sie mit Indizes beginnen sollte: person(department, primarycontact, pid) und contact(pid, contacttype, home, mobile). Wenn Sie TOP verwenden, hätten Sie normalerweise eine ORDER BY Klausel.

+0

Danke, ich werde Index hinzufügen und die Leistung überprüfen. Gibt es einen anderen Bereich für das Umschreiben der Abfrage? – Sharmi

0

Erste, warum Sie benötigen 10 Millionen Datensatz auf einmal? (Paging?)

Sie Ihre Abfrage wie folgt umschreiben kann, beheben den Fehler, klare Cache dann laufen.

SELECT 
    ID, NAME, DEPARTMENT, 

      (SELECT TOP 1 CASE when ContactType='MOBILE' then MOBILE else Home end 
       FROM dbo.CONTACT with (nolock) 
       WHERE CONTACT.PID = PERSON.PID 
       and ((PrimaryContact = 'MOBILE' and ContactType = 'MOBILE') or (PrimaryContact != 'MOBILE' and ContactType = 'Home'))) 

FROM 
    dbo.PERSON P with (nolock) 
WHERE 
    DEPARTMENT = @DEPARTMENT 

Auch Sie können innere Verbindung mit ähnlichen Bedingungen verwenden und überprüfen Sie sich.

mein Index suggesation,

clustered index on person.PID 
clustered index on contact.PID 
non clustered index on person.DEPARTMENT include(name,PrimaryContact) 
non clustered index on contact.ContactType include(MOBILE,Home)