我有一个大表,其中包含40亿多行和50列,其中大多数为datetime
或numeric
,少数为varchar
。
数据将每周(约2000万行)插入表中。
我希望在某些datetime
列和几个varchar
列上使用where子句进行查询。表中没有主键。
没有索引,也不对表进行分区。我正在使用SQL Server2016。
我知道我需要对表进行分区或建立索引,但是我不确定采用哪种方法或实际上两种方法都可以。
由于表很大,我应该首先创建索引还是应该首先创建分区?如果我确实创建了索引,然后又创建了分区,那么我应该怎么做以每周提供新数据来维护这些索引。
编辑:此外,该表上的更新和删除操作应最少进行
答案 0 :(得分:3)
我了解我需要对表进行分区或索引
您需要了解从分区中获得的收益。根本不是SQL Server要求对大表进行分区才能正常运行。 SQL Server可以扩展到任意表大小,而没有任何固有问题。
分区的共同好处是:
有时在特殊情况下(例如列存储),分区可以帮助加快查询速度。通常,索引会更好。
本质上,分区将表物理上拆分为多个子表。大多数情况下,这会对查询计划产生负面影响。索引完全有能力限制需要触摸的数据集。分区更糟糕。
大多数查询将在datetime列和某些varchar列上进行过滤。像这样,获取特定实体在特定日期范围内的数据。有了索引,由于要插入新的索引,它将导致很多碎片,并且重建/重新组织索引也将花费大量时间。我可以做到,但又不确定哪种方法。
看来您最好通过编制索引来解决此问题:
由于表很大,我应该首先创建索引还是应该首先创建分区?
首先设置该分区对象。然后,在新的分区方案上创建或重建聚簇索引。如果可能,请先删除其他索引,然后再重新创建它们(由于可用性限制,可能无法正常工作)。
我应该怎么做以每周提供新数据来维护这些数据。
您有什么担忧?新数据将自动存储在适当的分区中。确保在加载数据之前创建新分区。提前两周准备好分区。最新的分区必须始终为空,以避免昂贵的拆分。
表中没有主键。
通常这不是一个好的设计。大多数表应具有主键和聚集索引。如果没有自然密钥,请使用诸如bigint identity
之类的人工密钥。
您当然可以应用分区,但是我的感觉是,它将无法获得预期的效果。但是,这将迫使您承担额外的维护负担,可能会降低性能,并且存在犯错误的危险,从而威胁到可用性。简单很重要。