【发布时间】:2012-03-28 23:52:41
【问题描述】:
我为视图中使用的查询创建了两个选项,它们返回我需要的结果。我需要重写任一选项,以便可以在 Indexed View 中使用它。都失败了 在视图上创建唯一聚集索引时。第一个因 LEFT OUTER JOIN 而失败,第二个因子查询而失败。我相信两者都会失败,因为 自加入。
找到Creating Indexed Views后,有一大串无法使用的TSQL语法元素。其中:派生表、UNION、EXCEPT、INTERSECT、子查询、 外连接或自连接、TOP、ORDER BY、DISTINCT、MAX...
对于每个唯一的Company,查询应该获得最大的CompanyID。 Statuses 表中的 StatusName 也需要显示,我只是添加它以防它影响
解决方案。当前是INNER JOIN,因此不会导致创建索引出现问题。
Companies 表的示例,所有 3 列都是 INT:
CompanyID Company Revision
1 1 1
2 1 2
3 2 1
4 2 2
查询应该返回:
CompanyID Company Revision
2 1 2
4 2 2
这是我创建的两个选项:
SELECT t1.CompanyID, t1.Company, t1.Revision, Statuses.StatusName
FROM dbo.Companies AS t1
LEFT OUTER JOIN dbo.Companies AS t2
ON t1.Company = t2.Company AND t1.CompanyID < t2.CompanyID
INNER JOIN dbo.Statuses
ON dbo.Statuses.StatusID = t1.StatusID
WHERE t2.Company IS NULL
还有一个:
SELECT t1.CompanyID, t1.Company, t1.Revision, Statuses.StatusName
FROM dbo.Companies AS t1
INNER JOIN dbo.Statuses
ON dbo.Statuses.StatusID = t1.StatusID
WHERE t1.Company NOT IN (SELECT t2.Company from dbo.Companies AS t2 WHERE t1.CompanyID < t2.CompanyID)
所以,我的问题是,是否可以重写任一查询以在索引视图中使用?
我使用的是 MS SQL Server 2008 R2 和 2005。
【问题讨论】:
-
为什么您认为解决您遇到的任何问题(但您没有说明)的唯一解决方案是索引视图?您能否说明您的实际问题,而不是告诉我们为什么不能使用索引视图来解决它?
-
对不起,让我澄清一下。我们的硬件性能有限,并且正在寻找一种方法来提高查询性能,同时尽可能少地更改数据库模式。非索引视图已经到位。基表(本例中为公司)中将有 100,000 条记录,但通常从任何视图返回的记录少于 100 条。如果可以重写相当简单的查询,那么索引视图似乎是一个很好的解决方案。
-
如果您找到了一种构造结果集的方法并且它在“禁止”列表中,那么构造相同结果集的任何其他方法也可能会失败。索引视图的限制列表不仅仅是随机选择的——它们与索引在幕后的实现方式有关。
-
替代方案:重新设计 - 已经看到了您的目标。如果您安排行的最新版本始终具有 NULL Revision 值,那么您可以基于 that 创建索引视图。此外,您可以强制执行每个公司只有一个非 NULL 修订的约束。当然,插入会出现问题(插入新时必须在现有行中分配修订),因此您必须切换到
MERGE(并接受将在插入之后分配修订) -
(当我说非 NULL 时,我的意思是 NULL:每个公司只能强制执行一个 NULL 修订版)
标签: sql sql-server tsql clustered-index