0

我对分区和策略、如何以及何时使用它有一些疑问。正如我从SQL Server 2005 中的分区表和索引中了解到的那样,分区不仅用于可管理性,还用于提高超大型数据库表 (VLDB) 的性能。我们有一个包含数百万条记录的表。该表存储性能数据,例如指定项目被点击的次数等。我们需要每天在实际应用中评估当前月份的这些数据。我要防止的是将数据从一个表移动到另一个表,只是因为性能。我的想法是:我在这个 VLDB 上按当年创建分区。然后我会在表和分区方案的日期字段上创建聚集索引。我不知道我是否理解正确,但除此之外,该索引将分别为每个分区创建。

通常我的代码在开发阶段的样子。

/*
Maybe it looks like complicated, but instead of static upper bound, 
I use function to determine end of the month for the current year.

So for example (executed in year 2009)
    SELECT DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1901)*12)+1-1,31-1)) 
returns 
    2008-01-30 23:59:59.997
*/
CREATE PARTITION FUNCTION PartitionMonthlyCurrentYear(DATETIME) AS
RANGE LEFT FOR VALUES
(
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1901)*12)+1-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+1-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+2-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+3-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+4-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+5-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+6-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+7-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+8-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+9-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+10-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+11-1,31-1)),
    DATEADD(ms, -2, DATEADD(month,((DATEPART(YEAR, GetDate())-1900)*12)+12-1,31-1))
);

/*
Create scheme on the primary file group. I'm aware about performance issues of this.
*/
CREATE PARTITION SCHEME SchemeMonthlyCurrentYear 
AS PARTITION PartitionMonthlyCurrentYear
ALL TO ([PRIMARY]);

/*
Create clustered index on table and scheme
*/
CREATE CLUSTERED INDEX [IX_Log_Seiten_archive_Datum] ON [dbo].[Log_Seiten_archiv] 
(
    [Datum] DESC
)ON SchemeMonthlyCurrentYear(Datum)
GO

我的问题:

  1. 您如何看待这种方法?
  2. 如何从指定的分区方案中删除表?如果我删除索引,仍然无法删除方案和功能,因为仍然依赖表Log_Seiten_archiv
  3. 如何分配表以使用不同的分区功能?由于开发,我需要经常更改分区功能的定义方式,或创建新分区功能。我该如何为现有表执行此操作?例如,我想更改我之前展示的功能的年份。

问候安东卡尔奇克

4

2 回答 2

2
  1. 不能使用 getdate() 等非确定性函数创建 SQL Server 分区函数。如果您使用跨越 10 年的数据填充数据库,然后简单地停止并观察 SQL Server 运行几年,您会看到 SQL Server 随着日期的变化将该数据从一个分区移动到另一个分区。SQL Server 分区不能那样工作。当调用分区函数时,数据被放入一个特定的分区中,这就是它的结束。除非您想手动移动它,否则它不会再次移动。

  2. 要删除表上的分区,请应用不使用分区方案的新聚集索引。数据将被移动。(请注意,这将花费很长时间,具体取决于数据的大小和磁盘的速度 - 对于数 TB 的数据仓库,我们可能需要数小时甚至数天。)

  3. 要分配不同的分区函数,请使用新的分区函数应用新的聚集索引。不过,同样,如果您经常更改分区功能,重建将需要很长时间,并且分区可能不是您要寻找的答案。

对于具有不同驱动器阵列集的超过 1 亿行数据库,分区是一个很棒的解决方案,但听起来您只是将所有内容放在同一组驱动器、同一文件组上。你不会在那里看到性能的大幅提升。

此外,请注意分区仅在 SQL Server Enterprise Edition 中可用,在 Standard 中不可用。它在 Dev 中可用,但由于许可限制,您不能在生产中使用它。

于 2009-01-20T11:58:49.747 回答
0

谢谢你们的快速响应。

  1. 您确实是开发人员负责如何将数据传输到分区表中。有很多方法可以做到这一点,每种方法都有优点和缺点。我在Technet上找到了关于此的优秀文章。

我现在明白了,如何删除或重新分配分区功能。

这里的例子:

在现有表上创建分区:

CREATE CLUSTERED INDEX [IX_Log_Seiten_archive_Datum_Kanzleinr] ON [dbo].[Log_Seiten_archiv_Daily] 
(
    [Datum] DESC,
    [kanzleinr] ASC
)ON SchemeDailyCurrentYear(Datum) 
GO

删除现有表上的分区:

DROP INDEX [IX_Log_Seiten_archive_Datum_Kanzleinr] ON [dbo].[Log_Seiten_archiv_Daily];

CREATE CLUSTERED INDEX [IX_Log_Seiten_archive_Datum_Kanzleinr] ON [dbo].[Log_Seiten_archiv_Daily] 
(
    [Datum] DESC,
    [kanzleinr] ASC
)ON [PRIMARY]
GO

谢谢你的帮助阿卡

于 2009-01-22T11:53:24.390 回答