2017-12-20 1 views
2

Ich verwende einen Microsoft SQL Web Server auf Amazon RDS. Das System erzeugt derzeit Zeitüberschreitungen beim Aktualisieren einer Spalte. Ich versuche, das Problem zu lösen oder zumindest zu minimieren. Derzeit werden die Updates durchgeführt, wenn ein Gerät anruft und eine Menge angerufen wird, bis ein Gerät zurückruft, bevor der Webserver den letzten Anruf beendet hat.Spalte in MSSQL schnell aktualisieren

Microsoft SQL Server Web (64-bit) Version 13.0.4422.0

Ich sehe ein paar potentielle Möglichkeiten. Zuerst ruft das Gerät zurück, bevor das System den letzten Anruf bearbeitet hat, so dass derselbe Datensatz mehrmals gleichzeitig aktualisiert wird. Die zweite Möglichkeit ist, dass ich in ein Reihen- oder Tischschloss renne.

Die Tabelle enthält insgesamt etwa 3.000 Datensätze.

Hinweis Ich versuche nur jeweils eine Spalte in einer Zeile zu aktualisieren. Die anderen Spalten werden nie aktualisiert.

Ich brauche nicht die letzte aktualisierte Zeit, um sehr genau zu sein, würde es einen Vorteil geben, den Code zu ändern, um nur die Spalte zu aktualisieren, wenn sagen größer als ein paar Minuten oder würde das nur mehr Last hinzufügen Server? Irgendwelche Vorschläge, wie man das optimiert? Vielleicht verschieben Sie es zu einer Funktion, Speichervorgang oder etwas anderes?

Empfohlene neuen Code:

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

Bestehende Update-Code:

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 }); 
} 

Tabellenerstellungsskript:

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

erstellen Index für Lastupdated Spalte, und verwenden Sie DATEDIFF nicht verwenden Lastupdated Steve

+2

3000 Zeilen ist überhaupt keine Daten. Es ist nicht genug, die Register eines einzelnen Kerns zu füllen, geschweige denn seinen Cache. Wenn Sie * Timeouts * haben, gibt es ein anderes Problem. Sie versuchen möglicherweise, Zeilen zu ändern, die durch eine andere Transaktion/Verbindung gesperrt sind. Hast du den Aktivitätsmonitor in SSMS überprüft? Werden blockierte Sitzungen angezeigt? –

+0

Und warum verwenden Sie ApplicationDbContext, der von Identity verwendet wird? Sind Sie * sicher * hat es keine Transaktionen geöffnet? –

Antwort

0

Sie in die Ursache durch die Verwendung eines Werkzeugs, wie Profiler aussehen sollte oder andere Techniken zum Erkennen von Blockierungen. Ich sehe nicht, warum Sie ein Problem haben würden, eine Spalte Ihrer Tabelle mit nur 3.000 Aufzeichnungen zu aktualisieren. Es könnte etwas mit deinen Einschränkungen zu tun haben.

Wenn es wirklich ein Timing-Problem ist, dann können Sie im Speicher OLTP berücksichtigen, entwickelt, um diese Art von Szenario zu behandeln.

Last updated kann auch in einer transaktionsbasierten Tabelle mit einem Link zurück zu dieser Tabelle mit einem Join mit Max (UpdatedTime) gespeichert werden. In diesem Fall würden Sie niemals aktualisieren nur neue Datensätze hinzufügen.

Sie können dann entweder Partitionierung oder eine Aufräumroutine verwenden, um die Größe dieser Transaktionstabelle niedrig zu halten.

Programmiermuster, die In-Memory-OLTP verbessern umfassen Gleichzeitigkeit Szenarien Punkt-Lookups, Auslastungen, wo es viele Einfügungen und Aktualisierungen und Business-Logik in gespeicherten Prozeduren.

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

Verwandte Themen