大型事实表和分区键的困境

Sea*_*ean 5 clustered-index sql-server-2008-r2 partitioning nonclustered-index

我有相当大的事实表(20 亿条记录,大约 120 GB)。此表未分区,查询响应非常慢。我打算对表和索引进行分区。该表有一个标识列,它是主键并在其上有一个聚集索引。还有其他非聚集索引,但我不会在这里详细介绍。我试图分区的列不是主键的一部分,但不是空的,这给我带来了轻微的困境。我有两个选择。

  1. 我将此列添加为主键的一部分,即复合主键。由于第一列是标识,组合将始终是唯一的,这意味着我不必担心访问表的应用程序。聚集索引将自动分区对齐,其他索引也可以分区对齐。

  2. 秒选项是删除标识列上的聚集索引并使其唯一非聚集。该索引不能分区对齐,因为分区键不是它的一部分,因此必须位于一个驱动器上。然后在分区键列上创建一个聚集索引,该列可以分区对齐,因此所有其他非聚集索引。

我们的 DBA 支持第二种选择,因为他不想更改主键。我担心选项 2 中的性能下降,因为索引不是分区对齐的。

我将不胜感激任何反馈以及您在这种情况下会使用的任何其他方法。

Ali*_*ghi 1

我不想说显而易见的事情,但我想说测试这两种场景并对所有 3 个场景运行生产查询(场景 1 是当前的非分区场景)。我之所以这么说是因为我不知道你的代码正在查询什么。在基表中按标识列(而不是其他列)进行排序实际上有好处吗?例如,您的查询实际上是否经常查找行 ID?如果您不确定,您可能会对获得一些性能优势感到惊讶。使用 ID 作为聚集键的总体思路是用于范围扫描,但在我们的例子中,我们按 customerID 和日期进行扫描,因此它对我们(也许对您)来说非常适合。查看 Kim Tripp 撰写的这篇文章:\n http://www.sqlskills.com/blogs/kimberly/post/The-Clustered-Index-Debate-Continues.aspx

\n\n

“IDENTITY PRIMARY KEY 聚集索引定义中经常被引用的 \xe2\x80\x9creason\xe2\x80\x9d 是其单调性,从而最大限度地减少页面拆分。但是,我认为这是唯一的 \xe2\x80\ x9creason\xe2\x80\x9d 用于定义聚集索引,是列表中最差的原因。页拆分由适当的 FILLFACTOR 管理,而不增加插入。范围扫描是最重要的 \xe2\x80\x9creason\xe2\ x80\x9d 在评估聚集索引键定义和 IDENTITies 时并不能解决此问题。此外,虽然对 IDENTITY 代理键进行聚集会由于其单调性而最大限度地减少页拆分和逻辑碎片,但它不会减少 EXTENT FRAGMENTATION,这可能会导致页面分割等查询性能有问题。\n简而言之,参数运行得很浅\n"

\n\n

通常,您希望聚集索引尽可能窄、唯一且不可为空,因为它会被带入所有其他索引。我有一个包含大约 100 亿行的表,我们对日期时间列进行了分区,效果非常好。

\n