Sql server SQL Server索引设计,其中PK与行数据大小相同
我试图确认我的表需要主键,即使它会使行大小增加一倍,或者找出合适的索引策略。我们正在使用SQLServer2008R2 我有一个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行,格
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个节点上创建一个聚集索引,而不需要任何明显的空间使用增量。谢谢罗杰,您的字节总数是正确的。如果我在这三个字段上创建一个聚集索引(我确实认为这三个字段是唯一的或应该是唯一的),这会加快只涉及其中一个字段的查询速度吗?我的理解是,只有当查询使用索引中的所有列时,才会使用多列上的聚集索引。如果我错了,这将是个好消息!