【问题标题】:Perfomance tweak for this query此查询的性能调整
【发布时间】:2017-03-10 12:27:46
【问题描述】:

我正在编写以下查询,

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'

【问题讨论】:

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


【解决方案1】:

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

【讨论】:

  • 这个建议能在多大程度上提高性能?它对我来说似乎不是特别有用。
  • 人在哪里选择*?
  • @DanBracuk ,BD.* FROM
  • hmm..bd.* 是 cousing 问题,但不确定 bd.* 内部的哪个位置导致问题
  • @GordonLinoff 怎么没用?表名是 wv_BlogData。我假设它有 ntext 字段。
【解决方案2】:

覆盖索引

(查看您的执行计划,您似乎已经获得了适当的覆盖索引,但这是一个很好的一般建议,仍然值得一试)

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

查询更改

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

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

粗略查看您的查询,我可以看到的最明显的事情是您正在对 Cms_Class 执行内部连接,但没有从中选择任何数据,甚至没有将其连接到其他表(除了CMS_树)。我建议删除此连接并改用存在语句,如下所示:

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 内容,因为它太慢了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多