了解 SQL Server 2008 R2 中索引视图中的列类型
Posted
技术标签:
【中文标题】了解 SQL Server 2008 R2 中索引视图中的列类型【英文标题】:Understanding column type in indexed view in SQL Server 2008 R2 【发布时间】:2010-12-09 10:20:03 【问题描述】:我们通过这样的sql创建了一个索引视图:
Select Table1_ID, Count_BIG(*) as Table2TotalCount from Table2 inner join
Table1 inner join... where...
同样在创建视图之后,我们在 Table1_ID 列上设置了聚集唯一索引。 所以 View 由两列组成:
Table1_ID
Table2TotalCount
我们有两个问题:
-
如果我们使用
Count(1)
或Count_BIG(1)
而不是Count_BIG(*)
,SQL 不允许我们在 Table1_ID 上设置索引
我们如何控制第二列的类型 (Table2TotalCount
) - SQL 给出一个
long nullable 类型到此列。但是我们想为该列设置 int not nullable 类型。创建视图后,我们找不到任何更改列类型的方法。
还有我们用于创建视图的 t-sql,总是将 int 值返回到 Table2TotalCount。
【问题讨论】:
【参考方案1】:您必须使用 COUNT_BIG(*)。这是creating an indexed view的限制之一:
视图中的 SELECT 语句不能包含以下 Transact-SQL 语法元素:
COUNT(允许使用 COUNT_BIG(*)。)
您可以创建第二个未编入索引的视图,它引用第一个视图,并将计数列的数据类型转换为您想要的类型(并且可能使用 ISNULL() 来防止可空属性)
【讨论】:
【参考方案2】:这可能是因为您指望的是表达式而不是字段或 *
。使用count(1)
与count(*)
的结果相同,即计算记录数,因此没有理由使用count(1)
。
使用count
而不是count_big
来获得int
而不是bigint
(长)。 (文档特别指出,它们之间的唯一区别是返回类型。)我不知道为什么该值可以为空,因为 count
永远不会返回空值,但这对于所有聚合可能都是相同的,并且可能不可能控制。
【讨论】:
你读过为什么我们使用 count_big 而不是 count 吗?我们以后不能设置索引。不理解您对问题 1 的回答(关于表达式而不是字段)以及它与我们的问题的关系。如果您仅在返回类型中写入 count 和 cout_big 的差异 - 那么它如何影响在其他列上创建索引? count(1) 也比 count(*) 占用更少的资源 - 这就是我们要使用 count(1) 的原因。 @mmcteam.com.ua - 我认为最后一次 count(1) 使用的资源少于 count(*) 大约是 SQL Server 6.5。它可能是 4.2 或 7,但肯定已在 2000 年解决。 @mmcteam.com.ua:count
聚合有两种形式,count(expression)
或 count(*)
,因此 count(1)
是表达式 1
的计数。如果count_big(*)
有效但count_big(1)
无效,则使用count_big(*)
。由于表达式几乎可以是任何东西,因此如果您不能根据表达式的计数创建索引,这是非常合理的。以上是关于了解 SQL Server 2008 R2 中索引视图中的列类型的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 2008 R2 和索引视图中的执行计划