Sql server Sql Server-从VLT中删除列(非常大的表)
任何人都可以建议实现以下目标的最佳方法: 要求:从VLT(近400 gb)中删除5列 当我们尝试做同样的事情时,我们就面临生产上的空间问题、超时错误(通过SSM) 我们尝试在任何临时表中插入(通过关闭标识),但随后我们插入了所有近数十亿行数据,并尝试打开标识,我们面临超时错误 如果我们通过POWERSHELL执行这些操作,那么与在SSM中执行操作相比会更好 限制:生产空间有限,由于这些操作,tempdb增长迅速 请告知,从VLT中删除色谱柱的最佳方法是什么Sql server Sql Server-从VLT中删除列(非常大的表),sql-server,tsql,Sql Server,Tsql,任何人都可以建议实现以下目标的最佳方法: 要求:从VLT(近400 gb)中删除5列 当我们尝试做同样的事情时,我们就面临生产上的空间问题、超时错误(通过SSM) 我们尝试在任何临时表中插入(通过关闭标识),但随后我们插入了所有近数十亿行数据,并尝试打开标识,我们面临超时错误 如果我们通过POWERSHELL执行这些操作,那么与在SSM中执行操作相比会更好 限制:生产空间有限,由于这些操作,tempdb增长迅速 请告知,从VLT中删除色谱柱的最佳方法是什么 关于我想说的是另一个表和批处理作业的组
关于我想说的是另一个表和批处理作业的组合 1-创建一个具有所需结构的新表。使用与旧表相同的聚集索引键 2-创建一个视图来合并旧表和新表,以便在需要时可以连续访问这两个表。要限制生产中的问题,可以将其命名为与原始表相同的名称,并将该表重命名为_Old或其他名称。显然,只在视图中包含所需的字段,而不是要删除的字段 3-交易内部:
- 在新表中插入若干行(例如一次插入1m行或其他行)
- 从旧表中删除,在新表上加入
坏消息是,您正在删除记录,因此一旦开始,您基本上会致力于此过程。根据需要进行多少排序,您还可以从
UNION
视图中获得tempdb压力。我可能会考虑使用您想要的模式创建一个新的分区表,并将数据插入切换表,然后将这些表切换到新表中
如果您不太熟悉分区表和索引,我强烈推荐Kimberly Tripp的这一点
将数据插入交换机表时,可以通过执行以下操作强制执行最小日志记录:
INSERT newtable WITH (TABLOCK)
SELECT col1, col2, col3, col4
FROM oldtable
WHERE col1 BETWEEN min and max
祝你好运。我希望这是有用的。我在SQL Server中使用VLDBs,发现分区在加载和移动数据时非常宝贵。不能说我有过这样大的表的经验,但如果是我,我想尝试一下,我会尝试将数据(只保留列)BCP到O/S文件中,删除该表,然后将数据BCPing回一个新表,其中只包含我需要的列。当然,这假设您在进行维护时能够使服务器离线(并且在开始之前有良好的备份)。。。。DROP本身是一个仅元数据的操作,只要能够获得表上的独占锁,它几乎会立即完成,这意味着使用表的所有查询都必须排空(完成)。但是,删除列并不会实际删除它们,请参见 下一步是删除物理列(如果需要)。如果有必要,我会说“因为,根据列类型的不同,这可能不值得付出努力。”。对于可变长度列,可以通过运行来回收空间。但是,如果在未压缩的表上删除了固定大小的列(没有页面或行压缩),那么回收空间的唯一方法就是重新生成表(堆或聚集索引)。如果表已分区,您可以尝试一次脱机重建一个分区(
altertable…REBUILD partition=N
)。如果没有,最好的方法是在线重建,前提是您没有MAX type列(此选项)。在线重建会生成大量日志(至少是数据大小的1.5倍),但它会在内部提交,这样日志备份维护就可以回收空间,而不会导致600Gb的日志增长。如果在线重建不可行,并且表没有分区,那么我将首先重新考虑清理drop列的决定
如果列清理是绝对必须的,并且您没有在线选择,那么您真的将面临一个痛苦的世界。进行如此大规模的操作需要数天的准备、测试,而且一点也不琐碎。您必须创建一个具有所需结构的新表,开始批量向其中传输数据,并设置一些机制来跟踪对已复制数据所做的更改,然后将这些更改应用于副本。复制所有数据并应用自复制开始以来发生的更改后,可以使用切换新表和旧表。总之,如果你能使用现成的在线选项,你会更好 我将采用前面提到的方法之一,但有一些关键的修改。假设您使用的是SQL Server 2008,请执行以下操作:
select top 0 {{column subset}} into tbl_tableB from tableA
还要确保将所有索引、约束等复制到新表中。标识列将由SELECT…INTO
语句适当处理exec sys.sp_rename @objname = 'tableA', @newname = 'tbl_tableA'
create view tableA
as
select {{column subset}} from tbl_tableA
union all
select {{column subset}} from tbl_tableB
这将与查询数据的应用程序保持一定程度的兼容性
BEGIN TRAN
DELETE TOP (1000) /* or whatever batch size you want */
FROM
tbl_tableA
OUTPUT (
DELETED.{{column subset}} /* have to list each column here prefixed by DELETED. */
)
INTO
tbl_tableB (
{{column subset}} /* again list each column here */
)
/* Check for errors */
/* COMMIT or ROLLBACK */
/* rinse and repeat [n] times */
drop view tableA
drop table tbl_tableA
exec sys.sp_rename @objname = 'tbl_tableB', @newname = 'tableA'