Sql server SQL Server索引设计,其中PK与行数据大小相同

Sql server SQL Server索引设计,其中PK与行数据大小相同,sql-server,indexing,sql-server-2008-r2,large-data,Sql Server,Indexing,Sql Server 2008 R2,Large Data,我试图确认我的表需要主键,即使它会使行大小增加一倍,或者找出合适的索引策略。我们正在使用SQLServer2008R2 我有一个Testscores表,表中有20多亿行,每行只包含以下形式的10字节数据: (ItemID INT, ProjectID SMALLINT, DepartmentID SMALLINT, Score REAL). 没有一个列是唯一的,但我们有大约1亿个ItemID、500个ProjectID和300个DepartmentID 我有一个项目的查找表,大约有500行,格

我试图确认我的表需要主键,即使它会使行大小增加一倍,或者找出合适的索引策略。我们正在使用SQLServer2008R2

我有一个
Testscores
表,表中有20多亿行,每行只包含以下形式的10字节数据:

(ItemID INT, ProjectID SMALLINT, DepartmentID SMALLINT, Score REAL).
没有一个列是唯一的,但我们有大约1亿个ItemID、500个ProjectID和300个DepartmentID

我有一个
项目的查找表
,大约有500行,格式如下

(ID SMALLINT, ProjectName varchar, State Char(2), year INT)
最初,该表是非规范化的,大约为600gb。我的目标是能够查询关于
ProjectName
State
或年份(有时是其中一个,有时是两个,有时是全部三个)的projects表。然后,我将加入
ProjectsID
上的
Testscores
表,返回匹配项目的所有测试分数(大约500万到2000万个结果)

在重建表之后(愚蠢的人应该首先解决这个问题),我开始了解到,如果没有聚集索引,即使我在
ProjectsID
上构建了非聚集索引,每个查询也必须使用表扫描

我当前的行大小是10个字节,添加一个
BigInt
(需要,已经有20亿个字节了,而且还要添加更多)将为每行添加8个字节,基本上是我的数据库的两倍。在
ProjectsID
上构建非聚集索引本质上需要8个字节用于唯一化器(4个字节用于值,4个字节用于第一个varchar)

有什么想法吗?我是不是把数据库设计搞砸了?我不介意再重建一次,我只想把它做好

顺便说一句,我已经闹鬼十年了,这是我遇到的第一个通过搜索无法回答的问题。你们都很摇滚


编辑:当我将数据加载到表中时,它在
projectd ASC,ItemID ASC
上进行了预排序,如果这有什么区别的话。

由于每条记录的记录大小为8字节,SQL Server在每页上放置了大约1000行。这意味着任何选择超过0.1%数据的查询都很可能命中所有或几乎所有页面。在这些情况下,引擎通常选择全表扫描,而不是使用索引

考虑到您的查询返回至少500万行,我推测很难避免对表进行完整扫描。聚集索引可能有助于某些查询(也许通过一些奇迹),但并非对所有查询都有帮助


一件可能有帮助的事情是对表进行分区;但是,为了进行有效分区,您需要对数据进行非规范化。

谢谢Gordon!我们有企业版,所以分区是一种选择(我甚至比大型数据库更不熟悉)。testscores大约为50gb,因此表CAN是不幸的,但考虑到我们查询表的频率,它是可行的。这是一个很好的开始。另外,我会用一个更小的测试表(几百万行就足够了)。
Real
数据类型需要4个字节,而不是2个字节,所以行大小是4+2+2+4=12个字节,而不是10个字节。毕竟,这要多出20%。而且,在我看来,ProjectID+DepartmentID+ItemID列的组合很可能是唯一的。如果确实是这样,您可以在这3个节点上创建一个聚集索引,而不需要任何明显的空间使用增量。谢谢罗杰,您的字节总数是正确的。如果我在这三个字段上创建一个聚集索引(我确实认为这三个字段是唯一的或应该是唯一的),这会加快只涉及其中一个字段的查询速度吗?我的理解是,只有当查询使用索引中的所有列时,才会使用多列上的聚集索引。如果我错了,这将是个好消息!