我正在撰写以下查询,
仅加载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'
答案 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内容,因为它太慢了。