【问题标题】:Partition or Index large table in SQL ServerSQL Server 中的大表分区或索引
【发布时间】:2019-09-27 02:52:21
【问题描述】:

我有一个包含 40 亿多行和 50 列的大表,其中大部分是 datetimenumeric,除了少数是 varchar

数据将每周插入到表中(大约 2000 万行)。

我希望在某些 datetime 列和几个 varchar 列上使用 where 子句进行查询。表中没有主键。

没有索引,表也没有分区。我正在使用 SQL Server 2016。

我知道我需要对表进行分区或索引,但实际上我不确定采用哪种方法或两者兼而有之。

既然表很大,是先创建索引还是先创建分区?如果我确实创建了索引然后创建了分区,我应该如何维护这些以每周都有新数据。

编辑:此外,预计表上的更新和删除最少

【问题讨论】:

  • 分区和索引是出于非常不同的目的。索引更常见,我会首先查看需要快速的查询并创建索引来支持它们。
  • 感谢@VladimirBaranov。大多数查询将在 datetime 列和一些 varchar 列上进行过滤。例如,获取某个实体的某个日期范围的数据。使用索引,由于新的插入,它将被大量碎片化,并且重建/重组索引也会消耗大量时间。我可以做到,但再次不确定哪种方法。
  • There are no indexes, 这是个大问题。查询性能取决于索引。没有它们,服务器必须扫描整个 4B 行。分区是一种数据管理特性,不是一种性能特性。如果要按日期搜索,请索引日期列。
  • 另一种选择是创建clustered columnstore index,在压缩数据的同时有效地索引所有列。由于压缩、内存处理和列存储,列存储可以为数据仓库/星型模式场景提供 100 倍的加速。
  • @siddharth 这个表是干什么用的?是事实表吗?它是如何在没有索引的情况下增长到 4B 行的?如果您描述实际的用例/问题,您可能会得到更好的答案。

标签: sql-server indexing sql-server-2016 partitioning


【解决方案1】:

我了解我需要对表进行分区或索引

您需要了解您从分区中获得了什么。 SQL Server 根本不需要对大表进行分区才能充分发挥作用。 SQL Server 可以扩展到任意大小的表,没有任何固有问题。

分区的共同好处是:

  1. 在恒定时间内大量删除
  2. 旧分区的不同存储
  3. 不备份旧分区

有时在特殊情况下(例如列存储),分区可以作为一种加速查询的策略。通常情况下,索引会更好。

本质上,分区将表物理拆分为多个子表。大多数情况下,这会对查询计划产生负面影响。索引完全能够限制需要触及的数据集。分区更糟糕。

大多数查询将在 datetime 列和一些 varchar 列上进行过滤。比如,获取某个实体的某个日期范围的数据。使用索引,由于新的插入,它将被大量碎片化,并且重建/重组索引也会消耗大量时间。我可以做到,但再次不确定哪种方法。

看来你最好通过索引来解决这个问题:

  1. 根据您期望的查询进行索引。
  2. 正确维护索引。这不是太难。例如,在每周加载后重建它们。

由于表很大,是先创建索引还是先创建分区?

首先设置分区对象。然后,在新的分区方案上创建或重建聚集索引。如果可能,请先删除其他索引,然后再重新创建它们(由于可用性限制,可能无法正常工作)。

我应该怎么做才能维护这些每周都有新数据。

您有什么顾虑?新数据将自动存储在适当的分区中。确保在加载数据之前创建新分区。提前 2 周准备好分区。最新的分区必须始终为空以避免代价高昂的拆分。

表中没有主键。

这通常不是一个好的设计。大多数表应该有一个主键和一个聚集索引。如果没有自然密钥,请使用人工密钥,例如 bigint identity


你绝对可以应用分区,但我的感觉是它不会让你得到你所期望的。但这会迫使您承担额外的维护负担,可能会降低性能,并且有犯错误的风险,威胁到可用性。简单很重要。

【讨论】:

  • 如果您有后续问题,请发表评论。
  • OP 似乎描述了一个事实表,在这种情况下,列存储索引是合适的。不过我想知道,他们是如何在没有索引的情况下达到 4B 行的?
  • @usr - 非常感谢您的回答。我现在想我会先尝试创建索引。我担心的是重建索引可能需要大约 14 到 15 个小时,而且该表预计每年会增长 10 亿行,这可能是以后的问题。
  • @PanagiotisKanavos - 目前没有索引的原因是因为这是作为回填提供的数据转储。我需要设置新作业以每周获取数据并将其插入表中。
  • @siddharth 你真的需要解释你的用例,因为索引重建可以在企业版中在线完成,而只是不需要大多数情况下。毕竟索引会自动更新。列存储索引的 20M 行并不是很多数据 - 它是为更新 1M 行增量中的数据而构建的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 2014-12-19
  • 1970-01-01
  • 2010-09-23
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多