为什么我们在 sql server 2005 中有 249 个非聚集索引?为什么不是 240 或 300?和 sql server 2008 的相同问题,为什么 999 ?为什么不是 800 或 1000?
5 回答
他们正在制作漂亮(四舍五入)的数字......
SQL Server 2005: 1 个聚集索引 + 249 个非聚集索引 = 每个表 250 个索引
SQL Server 2008: 1 个聚集索引 + 999 个非聚集索引 = 每个表 1000 个索引
更新:
您应该在 SQL Server 2008 中询问为什么 999。
这已在回答我的问题时进行了解释。这种增加是通过在 SQL Server 2008 中引入过滤索引来解释的。
sysindexes 中 index_id的数据类型意味着:
- 0 表示堆
- 1 - 聚集索引
- >1 非聚集
- >=3200 - XML 索引
因此,我们仍然可以观察到在 SQL Server 的未来版本中增加到 3198(3199-1)。
我之前认为 sys.indexes 是 sysindexes 的同义词,但我现在发现它们是不同的,sysindexes 具有 indid(而不是 index_id)并且不包含 XML 索引的行!
sys.indexes 中的 index_id 具有 int(4bytes) 类型,sys.sysindexes 中的 indid 具有 smallint (2bytes) 类型(SQL Server 2008,可能从以前的版本增加)
好吧,对于 SQL Server 2005 及更早版本..
- 0 = 堆。每个表在 sys.indexes 中至少有一个条目,即使它没有索引
- 1 = 聚集
- 255 = 对于 LOB 列的 SQL Server 2000 和更早版本(现在不记得为什么了)
因此,您立即拥有最多 253 个 NC 索引(2 到 254)。
四舍五入?还是一些旧版 SQL Server 7.0/6.5/6.0/4.2 的原因?
AFAIK 它们只是任意限制,很少有人在实践中遇到过。大概他们需要设置一些最大限制,以便他们知道在其内部结构中分配多少空间。也许他们只是决定decimal(3,0)
存储 indexid 就足够了!
如果他们允许1000
在 SQL Server 2008 中使用,您会问为什么不这样1001
做?
它基本上是一个内部实现限制。它不是由元数据大小(即 index_id 的 tinyint 列或小的 int 列)驱动的,而是反映内部限制的元数据列。
每当出现这样的限制时,就意味着在代码中的某处存在处理这种限制的实际限制。举个例子,如果查询计划的生成必须考虑同一张表上的数万个索引,那么查询计划的生成可能会变得过于复杂,并且即使是一个微不足道的计划也需要更多的时间来生成。面对此类问题时,会在被视为“合理”的数字上划出一条线。在 90 年代后期,大约 250 个指数似乎是合理的,在 R2 中限制被推到了 1000。
SQL Server 的早期版本会使用 tinyint 字段作为索引 ID。Tinyint 的最大值为 255。设计团队可能已将其向下舍入为 250,以便于记忆(就像他们对 varchar 字段的 8000 个字符限制所做的那样)。250 个索引被拆分:1 个聚集索引和 249 个非聚集索引。