针对此查询的性能调整

时间:2017-03-10 12:27:46

标签: sql sql-server performance performance-testing database-performance

我正在撰写以下查询,

Execution plan

仅加载80行需要30秒。

我们可以做些什么来减少运行此查询的时间吗?

select 
   CO.ContributorsName [ContributorsName]
 , D.DocumentLastPublished DocumentLastPublished
 , CO.ContributorsImage [AuthorImage]
 , T.NodeAliasPath
 , D.DocumentID
 , BD.*
from CMS_Tree T
  inner join Cms_Class CC 
    on T.NodeClassID = CC.ClassID
   and CC.ClassName = 'wv.blogdata'
  inner join Cms_Document D 
    on T.NodeID = D.DocumentNodeID
  inner join WV_BlogData BD 
    on D.DocumentForeignKeyValue = BD.BlogDataID
   and COALESCE(BD.IsDeleted, 0) = 0
  inner join WV_Contributors CO 
    on BD.AuthorID = CO.ContributorsID
where (
  'ALL' = 'ALL'
  or category = 'All'
  )
 and DocumentCulture = 'en-US'

Execution plan

2 个答案:

答案 0 :(得分:0)

不要对所有表使用*。只需指定列名称所需的列。检查WHERE子句。

答案 1 :(得分:0)

覆盖索引

(看看你的执行计划,看起来你已经有了相应的覆盖索引,但这是一个很好的一般建议,还值得一试)

如果这是一个经常使用的查询,请确保您在所涉及的表上获得了适当的覆盖索引。有关如何识别潜在缺失索引的信息,请参见this MSDN页面。请注意,添加索引将提高查询性能,但代价是降低插入性能。您还需要确保已制定适当的维护计划,以确保您的索引不会出现碎片或不平衡。

查询更改

我还建议您尝试对查询进行一些更改并比较执行计划。

如果不查看数据库并尝试一些事情,很难提出任何有意义的建议。

从粗略看看你的查询,我可以看到的最明显的事情是你在Cms_Class上执行内连接,但是没有从中选择任何数据,或者甚至将它连接到其他表(除了CMS_Tree)。我建议删除此连接并使用exists语句,如下所示:

select 
   CO.ContributorsName [ContributorsName]
 , D.DocumentLastPublished DocumentLastPublished
 , CO.ContributorsImage [AuthorImage]
 , T.NodeAliasPath
 , D.DocumentID
 , BD.*
from CMS_Tree T
  inner join Cms_Document D 
    on T.NodeID = D.DocumentNodeID
  inner join WV_BlogData BD 
    on D.DocumentForeignKeyValue = BD.BlogDataID
   and COALESCE(BD.IsDeleted, 0) = 0
  inner join WV_Contributors CO 
    on BD.AuthorID = CO.ContributorsID
where (
  'ALL' = 'ALL'
  or category = 'All'
)
and DocumentCulture = 'en-US'
and exists
(
  select null
  from Cms_Class CC 
  where T.NodeClassID = CC.ClassID
  and CC.ClassName = 'wv.blogdata'
)

试一试,查看执行计划,看看它是否会对您产生影响。

如果您创建新的覆盖索引,请重新运行查询并再次查看执行计划,因为在您添加索引后,缺少索引的最有效查询可能不是最有效的查询。

文档缓存(SQL并不总是访问数据的最佳解决方案)

假设您已经完成了这两项工作,并且查询性能仍然太差,您可能想问问自己是否确实需要查询实时数据。查看您的查询,看起来您正在查询来自CMS的数据。 CMS中的数据仅在内容作者实际进行更改时才会更改。大多数情况下,数据将从请求到请求保持不变。这意味着每次要访问内容时从SQL执行直接查询可能会因您的需要而过度。

一个很好的用例示例是查看Umbraco CMS如何访问其数据。它保留给定站点上所有已发布文档的XML文档缓存。当内容作者发布更改时,它会更新XML文档缓存。

访问缓存比直接与SQL交谈更有效,甚至警告用户不要使用他们的SQL API来提供CMS内容,因为它太慢了。