我在Amazon RDS上使用Microsoft SQL Web服务器。系统当前正在更新一列时生成超时,我正在尝试解决问题或至少将其最小化。目前,当设备呼入并且他们大量呼叫时,更新发生在设备可以在网络服务器完成最后一次呼叫之前回叫的位置。
Microsoft SQL Server Web(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
答案 0 :(得分:0)
您应该通过使用分析器或其他技术等工具来检测阻塞。我不明白为什么你只有3000条记录更新你的表一列时会遇到问题。它可能与你的约束有关。
如果它确实是一个计时问题,那么你可以考虑在内存OLTP,旨在处理这种类型的场景。
上次更新也可以存储在基于事务的表中,其中包含使用Max(UpdatedTime)的连接返回此表的链接。在这种情况下,您永远不会只更新添加新记录。
然后,您可以使用分区或清理例程来保持此事务表的大小。
内存中OLTP将改进的编程模式包括 并发场景,点查找,有很多的工作负载 在存储过程中插入和更新以及业务逻辑。