c# - 快速更新 MSSQL 中的列

标签 c# sql-server amazon-ec2

我在 Amazon RDS 上使用 Microsoft SQL Web 服务器。系统当前在更新一列时产生超时,我正在尝试解决该问题或至少将其最小化。目前,更新发生在设备呼入时,并且他们呼入很多,以至于设备可能在网络服务器完成最后一次调用之前回调。

Microsoft SQL Server 网站(64 位) 版本 13.0.4422.0

我在这里看到了一些潜在的可能性。首先是设备在系统完成处理最后一次调用之前回调,因此同一条记录被同时更新多次。第二种可能性是我遇到了行锁或表锁。

该表总共有大约 3,000 条记录。

请注意,我一次只尝试更新一行中的一列。其他列永远不会更新。

我不需要让上次更新时间非常准确,将代码更改为仅在大于几分钟的情况下更新列是否有任何好处,或者只会增加服务器的负载?关于如何优化这个的任何建议?也许将其移至函数、存储过程或其他内容?

建议的新代码:

UPDATE [Devices] SET [LastUpdated] = GETUTCDATE()
WHERE [Id] = @id AND 
([LastUpdated] IS NULL OR DATEDIFF(MI, [LastUpdated], GETUTCDATE()) > 2);

现有更新代码:

internal static async Task UpdateDeviceTime(ApplicationDbContext db, int deviceId, DateTime dateTime)
{
    var parm1 = new System.Data.SqlClient.SqlParameter("@id", deviceId);
    var parm2 = new System.Data.SqlClient.SqlParameter("@date", dateTime);
    var sql = "UPDATE [Devices] SET [LastUpdated] = @date WHERE [Id] = @Id";
    // timeout occurs here.
    var cnt = await db.Database.ExecuteSqlCommandAsync(sql, new object[] { parm1, parm2 });
}

建表脚本:

CREATE TABLE [dbo].[Devices](
[Id] [int] IDENTITY(1,1) NOT NULL,
[CompanyId] [int] NOT NULL,
[Button_MAC_Address] [nvarchar](17) NOT NULL,
[Password] [nvarchar](max) NOT NULL,
[TimeOffset] [int] NOT NULL,
[CreationTime] [datetime] NULL,
[LastUpdated] [datetime] NULL,
CONSTRAINT [PK_Devices] PRIMARY KEY CLUSTERED 
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,   ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO
ALTER TABLE [dbo].[Devices] ADD  CONSTRAINT [DF_Devices_CompanyId]  DEFAULT ((1)) FOR [CompanyId]
GO
ALTER TABLE [dbo].[Devices] ADD  CONSTRAINT [DF_Devices_TimeOffset]  DEFAULT ((-5)) FOR [TimeOffset]
GO  
ALTER TABLE [dbo].[Devices] ADD  CONSTRAINT [DF_Devices_CreationTime]  DEFAULT (getdate()) FOR [CreationTime]
GO

ALTER TABLE [dbo].[Devices] ADD  CONSTRAINT [PK_Devices] PRIMARY KEY CLUSTERED 
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

最佳答案

您应该使用分析器等工具或其他检测阻塞的技术来调查原因。我不明白为什么您在更新表中只有 3,000 条记录的一列时会遇到问题。这可能与您的约束有关。

如果真的是时序问题,那么可以考虑内存中的OLTP,专为处理此类场景而设计。

上次更新也可以存储在基于事务的表中,并使用 Max(UpdatedTime) 连接返回该表。在这种情况下,您永远不会更新,而只是添加新记录。

然后您可以使用分区或清理例程来减小此事务表的大小。

Programming patterns that In-Memory OLTP will improve include concurrency scenarios, point lookups, workloads where there are many inserts and updates, and business logic in stored procedures.

https://msdn.microsoft.com/library/dn133186(v=sql.120).aspx

关于c# - 快速更新 MSSQL 中的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47911201/

相关文章:

c# - 在 C# 中更新 NHibernate 3.3 中的子级

c# - 对 Web 方法的 Ajax 调用在内容类型设置为 ` application/json; charset=utf-8` 时不起作用

sql-server - 如何从 PowerShell 中的对象中删除 NULL 字符 (0x00)

sql - 通过存储过程检查数据库中的日期时间是否超过 90 天

c# - 如何在 WPF 中向后播放视频?

C# 从循环中启动线程抛出 IndexOutOfBoundsException

c# - 从 SQL 查询中捕获计数

mysql - 当我访问 amazon-ec2 中的 mysqldb 时,远程访问被拒绝。 (1045, "Access denied for user ' 用户名' @'some-ip' )

elasticsearch - Logstash Elasticsearch 输入 - 仅运行一次?

amazon-ec2 - 为什么我的额外自动扩展 EC2 实例无法终止?