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