0

我有一个很大的合同表,并且我们有许多存储过程来查询状态为 Open 的合同。只有不到 10% 的合约是开放的,而且随着数据库的增长,这个数字正在缩小。我想我可以创建一个未结合约的索引视图,以加快我们的一些查询。问题是状态不在合同表上,我需要一个子查询来检索我想要的数据。(SQL Server 然后在我查看的查询中对整个表进行聚集索引扫描)

这是视图的精简版(我从合约表中删除了其他 30 列)

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE VIEW [dbo].[vw_OpenContractsIndexed]
WITH SCHEMABINDING 
AS
SELECT     c.ContractID
FROM         dbo.NMPT_Contract AS c INNER JOIN
                      dbo.NMPT_ContractStatus AS cs ON c.ContractID = cs.ContractID AND cs.ContractStatusCreated =
                          (SELECT     MAX(ContractStatusCreated) AS Expr1
                            FROM          dbo.NMPT_ContractStatus AS cs2
                            WHERE      (ContractID = c.ContractID)) INNER JOIN
                      dbo.CMSS_Status AS s ON cs.StatusID = s.StatusID
WHERE     (s.StatusCode = 'OPN')

如果我尝试在视图上创建索引(唯一聚集在contractid)我得到以下

索引创建失败
它包含一个或多个不允许的构造。(Microsoft SQL Server,错误 1936)

从我可以收集到的问题是子查询中的最大值?

除了将状态放在合同表上(我个人认为它所属的位置)之外,还有什么建议可以优化这种情况。如果不这样做,其他版本的 SQL Server 是否会允许此索引视图?

4

3 回答 3

3

来自 TechNet 关于 SS 2000 中的索引视图:

视图定义的语法有几个限制。视图定义不得包含以下内容:

数数(*)

ROWSET 函数

派生表

自加入

清楚的

标准差、方差、平均值

Float*、text、ntext、image 列

子查询

全文谓词(CONTAIN、FREETEXT)

对可空表达式求和

最小值、最大值

最佳

外连接

联盟

您正在使用MAX, 和一个子查询,这两者都是不允许的。

要获得有关如何解决此问题的建议,您需要分享一些数据以及您正在尝试做的事情。

于 2012-07-12T16:12:46.747 回答
1

它不是“视图”解决方案,需要更多工作才能完成,但您可以创建非规范化表来保存视图的结果。这样,所有对 Open 合约的读取都可以与该表背道而驰。这将是最快的,但需要维护新表。

于 2012-07-12T16:27:39.453 回答
0

创建索引视图是一项非常困难的任务,因为它有很多限制,而且还与自连接有关。你有自己加入这里。没有其他意见等。

如果您在这种情况下仅使用像“OPEN”这样的单个状态,则此类主表的其他事情我建议不要加入表(带有状态代码的主表),只需声明 statusid 变量,然后存储状态的值在那里打开,然后在最终查询中使用该值。这将避免与主表的额外连接。

我建议您在最终语句中加入合同表之前将打开状态的数据存储在临时表中。您可以对 statusid、customerid 和 contractcreationdate 进行索引。然后强制此索引将contractId放入临时表中

 select contractid into #temp from NMPT_ContractStatus 
where statusid =@statusid group by contractid          
having     datefield = max(datefield)

现在将此临时表与合同表连接起来。

但在创建任何类型的索引之前,请确保这些索引的开销远低于您获得的收益。

于 2012-07-14T12:15:30.257 回答