优化 SQL Server 2008 查询

Posted

技术标签:

【中文标题】优化 SQL Server 2008 查询【英文标题】:Optimize SQL Server 2008 query 【发布时间】:2017-02-13 03:11:52 【问题描述】:

更新:编辑了表格别名。

我正在尝试查找是否可以重写以下查询以提高性能。我们最近开始注意到对查询的巨大性能影响。 Person 表接近 1000 万,Contact 表接近 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 表进行分区。

任何提高整体性能的建议将不胜感激。

谢谢

【问题讨论】:

您的查询在语法上远非正确,以至于没有意义。 DETAILS 是什么? 对不起,那是 PERSON.PID 而不是 DETAILS.PID 您是否查看过此查询的执行计划?他们显示什么?另外:您的表结构是什么,已经存在哪些索引? 【参考方案1】:

对于这个查询:

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 子句。

【讨论】:

谢谢,我会添加索引并检查性能。还有其他重写查询的范围吗?【参考方案2】:

首先为什么你需要1000万条记录?(分页?)

你可以像这样重写你的查询,修复错误,清除缓存然后运行。

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

即使您可以使用具有相似条件的内部连接并检查自己。

我的索引建议,

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)

【讨论】:

以上是关于优化 SQL Server 2008 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2008 上的查询优化

SQL Server 2008 R2:优化查询性能

SQL Server查询优化器执行计划“语句提前终止的原因:超时”

SQL Server2008优化之SET STATISTICS开关

如何使用过滤器和分页优化 SQL Server 查询?

有关 SQL Server 中的 SQL 查询提示的详细信息