具有分区问题的Sql Server主键

sca*_*cci 5 sql-server filestream sql-server-2008

我正在构建一个将被分区并包含FILESTREAM列的表.我遇到的问题是,似乎我必须有一个复合主键(FILE_IDFILE_UPLOADED_DATE),因为它FILE_UPLOADED_DATE是我的分区方案的一部分.那是对的吗?我不希望这是一个复合键,只是只是FILE_ID作为主键.....这可能只是一个用户错误?

任何建议,将不胜感激.

版本:SQL Server 2008 R2

分区方案和功能:

CREATE PARTITION FUNCTION DocPartFunction (datetime)
AS RANGE RIGHT FOR VALUES ('20101220')
GO
CREATE PARTITION SCHEME DocPartScheme AS
PARTITION DocPartFunction TO (DATA_FG_20091231, DATA_FG_20101231);
GO
CREATE PARTITION SCHEME DocFSPartScheme AS
PARTITION DocPartFunction TO (FS_FG_20091231,FS_FG_20101231);
GO
Run Code Online (Sandbox Code Playgroud)

创建声明:

CREATE TABLE [dbo].[FILE](
    [FILE_ID] [int] IDENTITY(1,1) NOT NULL,
    [DOCUMENT] [varbinary](max) FILESTREAM  NULL,
    [FILE_UPLOADED_DATE] [datetime] NOT NULL,
    [FILE_INT] [int] NOT NULL,
    [FILE_EXTENSION] [varchar](10) NULL,
    [DocGUID] [uniqueidentifier] ROWGUIDCOL  NOT NULL UNIQUE ON [PRIMARY],
CONSTRAINT [PK_File] PRIMARY KEY CLUSTERED
    (   [FILE_ID] ASC
    ) ON DocPartScheme ([FILE_UPLOADED_DATE])
)ON DocPartScheme ([FILE_UPLOADED_DATE])
FILESTREAM_ON DocFSPartScheme;
Run Code Online (Sandbox Code Playgroud)

如果我不包括错误FILE_UPLOADED_DATE:

Msg 1908, Level 16, State 1, Line 1
Column 'FILE_UPLOADED_DATE' is partitioning column of the index 'PK_File'. Partition columns for a unique index must be a subset of the index key.
Msg 1750, Level 16, State 0, Line 1
Could not create constraint. See previous errors.
Run Code Online (Sandbox Code Playgroud)

谢谢!

Rem*_*anu 10

您将主键和聚簇索引混淆.这两者没有理由是同一个.您可以拥有聚簇索引,FILE_UPLOADED_DATE并且可以使用单独的非群集主键FILE_ID.实际上,您已经为DocGUID列执行了类似的操作:

CREATE TABLE [dbo].[FILE](
    [FILE_ID] [int] IDENTITY(1,1) NOT NULL,
    [DOCUMENT] [varbinary](max) FILESTREAM  NULL,
    [FILE_UPLOADED_DATE] [datetime] NOT NULL,
    [FILE_INT] [int] NOT NULL,
    [FILE_EXTENSION] [varchar](10) NULL,
    [DocGUID] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    constraint UniqueDocGUID UNIQUE NONCLUSTERED ([DocGUID]) 
        ON [PRIMARY])
    ON DocPartScheme ([FILE_UPLOADED_DATE])
    FILESTREAM_ON DocFSPartScheme;

CREATE CLUSTERED INDEX cdx_File 
   ON [FILE] (FILE_UPLOADED_DATE)
   ON DocPartScheme ([FILE_UPLOADED_DATE])
   FILESTREAM_ON DocFSPartScheme;

ALTER TABLE [dbo].[FILE]
    ADD CONSTRAINT PK_File PRIMARY KEY NONCLUSTERED (FILE_ID)
    ON [PRIMARY];
Run Code Online (Sandbox Code Playgroud)

然而,这样的设计将导致不对齐的索引,这可能导致非常严重的性能问题,并且还阻止所有快速分区交换操作.请参阅分区索引的特殊指南:

每个排序表都需要最少的内存来构建.在构建与其基表对齐的分区索引时,使用较少的内存一次构建一个排序表.但是,在构建非对齐分区索引时,排序表是同时构建的.

因此,必须有足够的内存来处理这些并发排序.分区数越大,所需的内存越多.每个分区表的最小大小为40页,每页8 KB.例如,具有100个分区的非对齐分区索引需要足够的内存来同时对4,000(40*100)个页面进行串行排序.如果此内存可用,则构建操作将成功,但性能可能会受到影响.如果此内存不可用,则构建操作将失败

您的设计已经有一个DocGUID的非对齐索引,因此性能问题可能已经存在.如果必须保持索引一致,则必须承认选择分区方案的一个副作用:除非密钥包含分区键,否则不能再使用逻辑主键,也不能使用唯一约束强制.

最后,必须要问:为什么要使用分区表?它们总是比非分区的替代品慢.除非您需要ETL的快速分区切换操作(由于DocGUID上的非对齐索引,您已经开始使用),因此基本上没有动机使用分区表.(优先评论:FILE_UPLOADED_DATE上的聚集索引保证比'分区消除'更好的替代方案).


Phi*_*ley 5

分区列必须始终存在于分区表的聚集索引中。您想出的任何解决方法都必须考虑到这一点。