2017-02-13 215 views
0

更新:編輯表別名。優化SQL Server 2008查詢

我正在嘗試查找下面的查詢是否可以重寫以提高性能。最近我們開始注意到對查詢的巨大性能影響。人表已接近1000萬,聯繫表有近1700萬 記錄。

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 

每個人在聯繫表中可以有一個/多個移動/家庭電話號碼。根據主要聯繫人類型,它應該只根據PrimaryContact類型獲取一個電話號碼。

在附註中,我們也計劃根據DepartmentPerson表進行分區。

任何提高整體性能的建議將不勝感激。

感謝

+0

您所查詢的是被語法正確的,它並沒有什麼意義至今。什麼是「DETAILS」? –

+0

對不起,這是PERSON.PID而不是DETAILS.PID – Sharmi

+0

你看過**查詢的執行計劃**嗎?他們展示了什麼?另外:你的表結構是什麼,已經有了哪些索引? –

回答

0

對於此查詢:

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; 

你應該開始索引:person(department, primarycontact, pid)contact(pid, contacttype, home, mobile)

通常,當您使用TOP時,您將有一個ORDER BY子句。

+0

謝謝,我會添加索引並檢查性能。是否有其他範圍的重寫查詢? – Sharmi

0

首先,爲什麼你需要在同一時間(分頁?)

你可以重寫你這樣的查詢,修復bug千萬的記錄?,清除緩存再運行。

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 

即使您可以使用類似條件的內連接並檢查自己。

我的索引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)