In welchen Situationen wird varchar (max) bevorzugt
Kommentatoren haben diesen Punkt bereits ausführlich angesprochen. Ich würde sagen, dass dies im VARCHAR(MAX)
Allgemeinen sinnvoll ist, wenn Sie zu 100% sicher sind, dass die Spalte niemals Nicht-ASCII-Zeichen benötigt und die maximale Länge der Spalte entweder unbekannt ist oder mehr als 8.000 Zeichen beträgt. Sie können /programming/7141402/why-not-use-varcharmax für eine ähnliche Frage lesen .
Das Zeitlimit für Aktualisierungsverfahren ist abgelaufen
Basierend auf dem Ausführungsplan denke ich, dass ein Hauptfaktor, der die Leistung Ihres Updates beeinflusst, darin bestehen könnte, dass Sie einen Volltextindex für die zu aktualisierende Spalte haben und diesen CHANGE_TRACKING = AUTO
für diesen Volltextindex verwenden.
Das Skript am Ende dieser Antwort zeigt eine einfache Aktualisierungsanweisung für eine bescheidene Anzahl von Zeilen, bei denen die Leistung durch Hinzufügen eines solchen Volltextindex von 19 ms auf über 500 ms steigt.
Abhängig von den geschäftlichen Anforderungen für Ihre Volltextsuche können Sie möglicherweise den Volltextindex erstellen CHANGE_TRACKING = OFF
(mit dem dieser Aufwand nicht verbunden ist) und regelmäßig ausführen ALTER FULLTEXT INDEX...START FULL POPULATION
oder START INCREMENTAL POPULATION
die Daten der Tabelle mit dem Volltextsindex synchronisieren . Den BOL-Artikel finden Sie hier: https://msdn.microsoft.com/en-us/library/ms187317.aspx
-- Create test data on a new database
CREATE DATABASE TestFullTextUpdate
GO
USE TestFullTextUpdate
GO
CREATE TABLE dbo.fulltextUpdateTest (
id INT NOT NULL IDENTITY(1,1)
CONSTRAINT PK_fulltextUpdateTest PRIMARY KEY,
object_counter_name NVARCHAR(512) NOT NULL
)
GO
--13660 row(s) affected
INSERT INTO dbo.fulltextUpdateTest (object_counter_name)
SELECT object_name + ': ' + counter_name
FROM sys.dm_os_performance_counters
CROSS JOIN (SELECT TOP 10 * FROM master..spt_values) x10
GO
-- ~19ms per update
DECLARE @startDate DATETIME2 = GETDATE()
SET NOCOUNT ON
UPDATE dbo.fulltextUpdateTest SET object_counter_name = object_counter_name
SET NOCOUNT OFF
DECLARE @endDate DATETIME2 = GETDATE()
PRINT(DATEDIFF(ms, @startDate, @endDate))
GO 10
-- Add a fulltext index with the default change-tracking behavior
CREATE FULLTEXT CATALOG DefaultFulltextCatalog AS DEFAULT AUTHORIZATION dbo
GO
CREATE FULLTEXT INDEX ON dbo.fulltextUpdateTest (object_counter_name)
KEY INDEX PK_fulltextUpdateTest
WITH CHANGE_TRACKING = AUTO
GO
-- ~522ms per update
-- Execution plan, like the plan in your question, shows that we must
-- touch the fulltext_index_docidstatus for each row that is updated
DECLARE @startDate DATETIME2 = GETDATE()
SET NOCOUNT ON
UPDATE dbo.fulltextUpdateTest SET object_counter_name = object_counter_name
SET NOCOUNT OFF
DECLARE @endDate DATETIME2 = GETDATE()
PRINT(DATEDIFF(ms, @startDate, @endDate))
GO 10
-- Cleanup
USE master
GO
DROP DATABASE TestFullTextUpdate
GO
quelle