Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 编程夜间数据传输的最佳方法,标识列运行速度很快_C#_Sql_.net_Sql Server_Data Transfer - Fatal编程技术网

C# 编程夜间数据传输的最佳方法,标识列运行速度很快

C# 编程夜间数据传输的最佳方法,标识列运行速度很快,c#,sql,.net,sql-server,data-transfer,C#,Sql,.net,Sql Server,Data Transfer,我正在编写一个应用程序,它需要每天晚上将自己的数据库与另一个数据库同步。当数据被拉过来时,它也以相当复杂的方式通过编程进行转换 现在我看到两种可能的方法: 方法A:每天晚上我都会删除以前导入的所有行,并进行一次完整的重新导入,这种方法虽然昂贵,但易于编程、维护,总体上很健壮 方法B:我为每个导入的行保存对原始数据的引用,如果数据分别是新的、更改的或删除的,则执行插入、更新或删除操作(单独保留引用非常复杂,因为没有简单的一对一关系) 很明显,方法B更复杂,可能更容易导致错误,所以我更喜欢使用方

我正在编写一个应用程序,它需要每天晚上将自己的数据库与另一个数据库同步。当数据被拉过来时,它也以相当复杂的方式通过编程进行转换

现在我看到两种可能的方法:

  • 方法A:每天晚上我都会删除以前导入的所有行,并进行一次完整的重新导入,这种方法虽然昂贵,但易于编程、维护,总体上很健壮

  • 方法B:我为每个导入的行保存对原始数据的引用,如果数据分别是新的、更改的或删除的,则执行插入、更新或删除操作(单独保留引用非常复杂,因为没有简单的一对一关系)

很明显,方法B更复杂,可能更容易导致错误,所以我更喜欢使用方法A。但是,由于每天晚上插入大约100000行,随着时间的推移,identity列将运行得非常高。每晚简单重置为1不是一个选项,因为导入的行实际上与其他与数据传输无关的行混合,最后设置的行必须不受传输的影响


关于这一点,我的主要问题是,我们的“身份”专栏是否会很高(每年大约增加3600万)。它并不整洁,但最终会不会有性能上的冲击,如果我们达到最大int值会发生什么?是否有人面临过类似的挑战并可以分享他们的经验?

只要您的身份是64位整数或更好,您就可以管理。这并不理想,但它会工作几年,直到你决定你真的需要真正的重构

是的,你可以建立一个理想的解决方案,但听起来你现在需要一个“足够好”的解决方案。。。这就是方法A

最终会有一场表演热播吗

我不明白为什么会有。字段的大小是相同的(例如,32位),因此使用它的所有操作都将以相同的速度执行,无论字段的值是10还是2000000000

如果您的标识列为int(32位),则它将持续
2147483647/36000000=59年

很容易检查当达到最大2147483647时会发生什么。在tempdb中创建一个表。(我使用SQL Server 2008进行此测试)

将标识设置为高值:

USE [tempdb]
GO

DBCC CHECKIDENT ("[dbo].[BigTable]", RESEED, 2147483645);
尝试插入10行:

USE [tempdb]
GO

INSERT INTO [dbo].[BigTable]
([Data])
VALUES
(0)

GO 10
这是我在输出窗口中得到的结果:

Beginning execution loop

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)
Msg 8115, Level 16, State 1, Line 2
Arithmetic overflow error converting IDENTITY to data type int.
Arithmetic overflow occurred.
** An error was encountered during execution of batch. Continuing.
Msg 8115, Level 16, State 1, Line 2
Arithmetic overflow error converting IDENTITY to data type int.
Arithmetic overflow occurred.
** An error was encountered during execution of batch. Continuing.
Msg 8115, Level 16, State 1, Line 2
Arithmetic overflow error converting IDENTITY to data type int.
Arithmetic overflow occurred.
** An error was encountered during execution of batch. Continuing.
Msg 8115, Level 16, State 1, Line 2
Arithmetic overflow error converting IDENTITY to data type int.
Arithmetic overflow occurred.
** An error was encountered during execution of batch. Continuing.
Msg 8115, Level 16, State 1, Line 2
Arithmetic overflow error converting IDENTITY to data type int.
Arithmetic overflow occurred.
** An error was encountered during execution of batch. Continuing.
Msg 8115, Level 16, State 1, Line 2
Arithmetic overflow error converting IDENTITY to data type int.
Arithmetic overflow occurred.
** An error was encountered during execution of batch. Continuing.
Msg 8115, Level 16, State 1, Line 2
Arithmetic overflow error converting IDENTITY to data type int.
Arithmetic overflow occurred.
** An error was encountered during execution of batch. Continuing.
Batch execution completed 10 times.
结果是:

USE [tempdb]
GO

SELECT [ID] ,[Data]
FROM [dbo].[BigTable]
GO


ID  Data
2147483645  0
2147483646  0
2147483647  0


DBCC CHECKIDENT ("[tempdb].[dbo].[BigTable]", NORESEED);

Checking identity information: current identity value '2147483647', current column value '2147483647'.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
所以,是的,当你用尽所有的int值时会有问题。 您可以使用。它是64位(8字节,而不是16字节),并且将持续更长的时间:
9223372036854775807/36000000=25620478801
年 bigint的性能与64位计算机上的int几乎相同。它可能比int慢,因为它的大小是int的两倍,服务器必须向磁盘读/写两倍的字节,并使用两倍的内存

就性能而言,真正重要的是在删除大量行并向表中添加大量行之后,重新生成索引并更新表上的统计信息,因为所有统计信息都会严重扭曲。在这里,我指的是使用此表的系统其余部分的性能,而不是删除和添加行的过程


为了提高每晚删除许多行并添加大量行的同步进程的性能,考虑在更改之前启用表上的所有索引并启用(具有重建)更改后,它们将返回。

这个问题可能更适合程序员堆栈交换,因为它更适合于最佳实践和实现。:)您的标识列的数据类型是什么?是int/big int。请使用GUID作为唯一行标识符。在几十万年的使用期内,即使是在极高的插入量下,您也永远不会用完ID,也不应该重复使用ID。GUID因其长度而昂贵。我绝对不建议在这种情况下使用GUID。
GUID
是16字节,
BigInt
是17字节(
numeric
数据类型)<只要海报使用的是SQL Server 2008或更高版本,code>GUID
s的写入、读取、传输速度将比
BigInt
更快,存储成本也会更低。如果他使用的是旧的,
GUID
将不是本机数据类型,因此他将被迫使用字符串或二进制类型表示。感谢全面的反馈。
USE [tempdb]
GO

SELECT [ID] ,[Data]
FROM [dbo].[BigTable]
GO


ID  Data
2147483645  0
2147483646  0
2147483647  0


DBCC CHECKIDENT ("[tempdb].[dbo].[BigTable]", NORESEED);

Checking identity information: current identity value '2147483647', current column value '2147483647'.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.