如何纠正 T-SQL 视图中的性能不佳
Posted
技术标签:
【中文标题】如何纠正 T-SQL 视图中的性能不佳【英文标题】:How to correct poor performance in T-SQL view 【发布时间】:2013-05-24 17:17:40 【问题描述】:我有一个 ASP.NET MVC 应用程序,它使用我创建的 T-SQL 视图作为其数据模型的一部分。我能够提取视图数据,但性能很差。
如果我对 SQL Server 2008 中的视图执行 SELECT *
,则需要 20 多分钟才能返回所有 187,101 行。
如果我在视图上执行SELECT TOP 1000000
,我会在 2 秒内返回相同的 187,101 行。
所以我在视图设计中加入了TOP
语句,以尝试在 ASP.NET MVC 应用程序中获得更好的性能,但在 WebGrid 中加载结果仍然需要大约 6 秒。
显然我的视图设计中有一些东西会影响性能,但我不知道如何修复它。我阅读了有关聚集索引视图的信息,但我无法架构绑定视图,因为需要能够修改表。
这是我用来创建视图的SELECT
语句:
SELECT TRD.Description AS Pbm,
MV.ExtractHistoryMemberValueId,
MV.FieldDescription,
MV.FieldValue,
HM.ExtractHistoryMemberId,
HM.CaseNum,
HM.CertNum,
HM.ClmtNum,
HM.PlanNum,
EH.ExtractHistoryId,
EH.ExtractDate
FROM OutgoingAccumulators.ExtractHistoryMemberValues AS MV
INNER JOIN OutgoingAccumulators.ExtractHistoryMembers AS HM
ON (MV.ExtractHistoryMember = HM.ExtractHistoryMemberId)
INNER JOIN OutgoingAccumulators.ExtractHistories AS EH
ON (HM.ExtractHistory = EH.ExtractHistoryId)
INNER JOIN OutgoingAccumulators.Extracts AS EX
ON (EH.Extract = EX.ExtractId)
INNER JOIN Accumulators.Interfaces AS INF
ON (EX.Interface = INF.InterfaceId)
INNER JOIN Accumulators.TradingPartners AS TRD
ON (INF.TradingPartner = TRD.TradingPartnerId)
这是视图设计的图像:
【问题讨论】:
所有要加入的字段都有索引吗?你真的需要所有的列吗? FK 隐含索引,所以答案是肯定的。我会尝试仅使用基表开始您的查询,然后一次添加一个连接,以查看您的查询开始受到影响的位置。是否有任何锁争用,同时读取和写入同一个表?您是否将多个一对多查询链接在一起? 附带问题:为什么在网格视图中需要 187000 行?需要从服务器推送大量数据... 将 187,101 加载到 WebGrid 需要几秒钟。 OK,需要获取ajax正在发送的查询并查看查询计划。 Top X 并不是真正修复视图的方法。最有可能的顶部 x 导致了不同类型的连接。查看它是什么并将连接类型(散列、循环、合并)放入视图中。 【参考方案1】:我找到了解决方案。我向 ExtractHistoryMemberValues 表添加了一个非聚集索引,如下所示:
USE [ProcessingDB]
GO
CREATE NONCLUSTERED INDEX [IX_ExtractHistoryMember]
ON [OutgoingAccumulators].[ExtractHistoryMemberValues] ([ExtractHistoryMember])
INCLUDE ([ExtractHistoryMemberValueId],[FieldDescription],[FieldValue])
GO
视图现在在 2 秒内返回所有行。
这是新的执行计划:http://i.imgur.com/CiWkFT7.png
【讨论】:
以上是关于如何纠正 T-SQL 视图中的性能不佳的主要内容,如果未能解决你的问题,请参考以下文章
视图中的 SUM(...) OVER (ORDER BY ...) 导致性能不佳