Sql server 视图的TSQL查询需要很长时间

Sql server 视图的TSQL查询需要很长时间,sql-server,tsql,Sql Server,Tsql,我为一系列不同的报告创建了一系列视图。它们彼此构建最终视图,返回的记录不到5k。当我打开此视图时,运行不到一秒钟。如果我在collumn不为NULL的位置添加一个,则需要2分钟以上的时间。虽然这对于我不需要经常运行的报告来说很好,但还有一些报告我必须每周、每天运行,有时甚至更频繁地运行 我的解决方案是创建一个存储过程,从视图的数据生成一个表,并查询该表。我将存储过程设置为在定时报告自动触发之前运行。这可以正常工作,但每次我想要获得更新的报告时,都必须手动运行存储过程 有更好的办法吗 查看[MW_

我为一系列不同的报告创建了一系列视图。它们彼此构建最终视图,返回的记录不到5k。当我打开此视图时,运行不到一秒钟。如果我在collumn不为NULL的位置添加一个
,则需要2分钟以上的时间。虽然这对于我不需要经常运行的报告来说很好,但还有一些报告我必须每周、每天运行,有时甚至更频繁地运行

我的解决方案是创建一个存储过程,从视图的数据生成一个表,并查询该表。我将存储过程设置为在定时报告自动触发之前运行。这可以正常工作,但每次我想要获得更新的报告时,都必须手动运行存储过程

有更好的办法吗

查看[MW_Submitted_ROY]以查找提交的周财务数据。此视图将活动表与静态表中的历史数据组合在一起。我将静态表中的数据调整为与活动表相同的格式

SELECT     oe_po_no, cus_no, user_def_fld_1, user_def_fld_2, tot_sls_amt
FROM         MW_Submitted_Weeks_OldMacola
WHERE     MW_Submitted_Weeks_OldMacola.oe_po_no LIKE 'adv%'
UNION
SELECT     oe_po_no, cus_no, user_def_fld_1, user_def_fld_2, tot_sls_amt
FROM         oehdrhst_sql
WHERE     oehdrhst_sql.oe_po_no LIKE 'adv%'
查看[MW_Company_Weeks],为每个公司生成他们将提交当前和上一年度财务报告的所有可能的周数

SELECT     MW.MW_Weeks.Year, MW.MW_Weeks.Week, MW.MW_CompanyCodes.cmp_code
FROM         MW.MW_Weeks CROSS JOIN
                  MW.MW_CompanyCodes
 WHERE     (MW.MW_Weeks.WEDate <= GETDATE()) AND (MW.MW_Weeks.Year > YEAR(GETDATE()) - 2)
这将我们带到最后一个视图[MW_Missing_Weeks],它显示了缺失的周数,以及上一年提交的财务报告的价值。这就是添加'is not null'会花费很长时间的地方

 SELECT     MW.MW_Company_Weeks.Year, MW.MW_Company_Weeks.Week, MW.MW_Company_Weeks.cmp_code, bPrev.tot_sls_amt, bPrev.[Group], bPrev.cmp_name, bPrev.Owner, 
                  bPrev.SalesPersonNumber, bPrev.Description
 FROM         MW.MW_Company_Weeks LEFT OUTER JOIN
                  MW.MW_Submitted_Weeks_By_RBC_ROY ON MW.MW_Company_Weeks.cmp_code = MW.MW_Submitted_Weeks_By_RBC_ROY.cmp_code AND 
                  MW.MW_Company_Weeks.Year = MW.MW_Submitted_Weeks_By_RBC_ROY.Year AND MW.MW_Company_Weeks.Week = MW.MW_Submitted_Weeks_By_RBC_ROY.Week LEFT OUTER JOIN
                  MW.MW_Submitted_Weeks_By_RBC_ROY AS bPrev ON MW.MW_Company_Weeks.cmp_code = bPrev.cmp_code AND MW.MW_Company_Weeks.Year = bPrev.Year + 1 AND 
                  MW.MW_Company_Weeks.Week = bPrev.Week
 WHERE     (MW.MW_Submitted_Weeks_By_RBC_ROY.cmp_code IS NULL) AND bPrev.tot_sls_amt IS NOT NULL

在SSMS中,转到查询>显示估计的执行计划,或点击
Ctrl+L
。找到计划中百分比最高的部分,并查看是否有绿色的“缺失索引”。右键单击并选择“缺少索引详细信息”。这将创建创建索引的代码。您只需要添加索引名

它看起来像这样:

/*
USE [Your Database]
GO
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[YourTable] ([ColA])
INCLUDE ([ColB],[ColC])
GO
*/
/*
使用[你的数据库]
去
创建非聚集索引[]
在[dbo]。[YourTable]([ColA])
包括([ColB]、[ColC])
去
*/
这是一种创建索引的快速而肮脏的方法


您也可以使用查询执行计划来解决问题。这需要一些练习。

如果不了解更多关于表结构、索引之类的信息,就很难提出具体的建议。可能会查看执行计划,看看哪里会出现减速,看看如果没有索引,索引在哪里可能会有所帮助。听起来像是“.not null”导致了一些大的表格扫描,这让事情变慢了…@DavidW这些是我以前从未弄糟过的事情。是否要我包含执行计划xml?它相当大。您可以在SQL作业中调度SP。表中包含where子句的记录有多少?您在查询中使用的联接是否过多?如果你能包含你的视图查询,它有助于更好地理解technet.microsoft.com/en-us/library/dd171921(v=sql.100)。aspx@BClaydon它建议为我用历史数据创建的表创建一个索引。这使查询执行时间从2分钟减少到了5-9秒!!!现在,它建议在一张表上建立另一个索引,这个索引会被写入一吨,就像整天都在写一样。成本节约了40%,但我认为索引可以降低服务器的整体性能。我认为这不会对历史数据表产生任何影响,因为这种情况从未改变。建议?@dinno-任何时候向表中添加新数据时,都必须为该表上的所有索引重新编制数据索引(可以有许多索引)。因此,当数据进入时,事务表的性能会受到影响。你的问题是,对服务器的打击值得吗?更重要的是,快速报告还是快速服务器?您可以随时进行测试以查看发生了什么,如果愿意,可以删除索引。
/*
USE [Your Database]
GO
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[YourTable] ([ColA])
INCLUDE ([ColB],[ColC])
GO
*/