2017-02-13 144 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)