Ich habe eine große Tabelle, die ich aktualisieren muss. Es wird durch das folgende Beispiel definiert (aber mir ist wirklich massiv 1 M + Reihen und Spalten) ...Optimierung einer rekursiven SQL-Abfrage
CREATE TABLE T
([Errors] varchar(4), [MRN] int, [EPI] varchar(13), [WD] varchar(4));
INSERT INTO T
([Errors], [MRN], [EPI], [WD])
VALUES
(NULL, 107, 'IP00001070001', 'AMUM'),
(NULL, 107, 'IP00001070001', 'AMUM'),
(NULL, 107, 'IP00001070001', 'KNAP'),
(NULL, 107, 'IP00001070002', 'KNAP'),
(NULL, 107, 'IP00001070002', 'KNAP'),
(NULL, 107, 'IP00001070002', 'KNAP'),
(NULL, 107, 'IP00001070002', 'KNAP'),
(NULL, 381, 'IP00003810001', 'EAUS'),
(NULL, 381, 'IP00003810001', 'EAUS'),
(NULL, 381, 'IP00003810003', 'DOCK'),
(NULL, 381, 'IP00003810003', NULL),
(NULL, 45, 'IP00000450001', 'ASES'),
('__', 45, 'IP00000450002', NULL),
('__', 381, 'IP00003810002', NULL);
ich die WD Spalten dieser Datensätze aktualisieren müssen, die null WD Werte haben WD Wert entsprechen der erste Eintrag, wenn sie von [MRN] und [EPI] bestellt wurden. Die erforderliche Ausgabe wäre zum Beispiel:
Errors MRN EPI WD
NULL 107 IP00001070001 AMUM
NULL 107 IP00001070001 AMUM
NULL 107 IP00001070001 KNAP
NULL 107 IP00001070002 KNAP
NULL 107 IP00001070002 KNAP
NULL 107 IP00001070002 KNAP
NULL 107 IP00001070002 KNAP
NULL 381 IP00003810001 EAUS
NULL 381 IP00003810001 EAUS
NULL 381 IP00003810003 EAUS
NULL 381 IP00003810003 EAUS
NULL 45 IP00000450001 ASES
__ 381 IP00003810003 EAUS
__ 45 IP00000450002 ASES
__ 381 IP00003810002 EAUS
Mit den bearbeiteten Datensätzen am unteren Rand. Das ist was ich will. Allerdings ist diese Methode SLLLLOOOOWWW ... Sehr langsam, und aus gutem Grund bin ich über das gesamte Set Looping. Meine Fragen haben die Zieltabelle bereits indiziert:
- Wie kann ich diese Abfrage/Operation optimieren?
- Brauche ich hier sogar Rekursion?
Hier ist die gesamte Abfrage Testset jemanden zu helfen, die bereit ist, zu helfen:
IF EXISTS (
SELECT name
FROM sys.tables
WHERE name = N'T')
DROP TABLE [T]
GO
CREATE TABLE T
([Errors] varchar(4), [MRN] int, [EPI] varchar(13), [WD] varchar(4));
INSERT INTO T
([Errors], [MRN], [EPI], [WD])
VALUES
(NULL, 107, 'IP00001070001', 'AMUM'),
(NULL, 107, 'IP00001070001', 'AMUM'),
(NULL, 107, 'IP00001070001', 'KNAP'),
(NULL, 107, 'IP00001070002', 'KNAP'),
(NULL, 107, 'IP00001070002', 'KNAP'),
(NULL, 107, 'IP00001070002', 'KNAP'),
(NULL, 107, 'IP00001070002', 'KNAP'),
(NULL, 381, 'IP00003810001', 'EAUS'),
(NULL, 381, 'IP00003810001', 'EAUS'),
(NULL, 381, 'IP00003810003', 'DOCK'),
(NULL, 381, 'IP00003810003', 'DOCK'),
(NULL, 45, 'IP00000450001', 'ASES'),
('__', 381, 'IP00003810003', NULL),
('__', 45, 'IP00000450002', NULL),
('__', 381, 'IP00003810002', NULL);
IF EXISTS (SELECT *
FROM sys.indexes
WHERE name='idxEETEST' AND object_id = OBJECT_ID('T'))
DROP INDEX [idxEETEST] ON [T];
GO
CREATE NONCLUSTERED INDEX [idxEpiIPWardLoad]
ON [T] ([MRN], [EPI])
GO
DECLARE @sql NVARCHAR(MAX)
DECLARE @mrn INT
DECLARE @epi NVARCHAR(16)
DECLARE @get_rec CURSOR
SET @get_rec = CURSOR FOR
SELECT MRN, EPI
FROM T
WHERE Errors IS NOT NULL
OPEN @get_rec
FETCH NEXT
FROM @get_rec INTO @mrn, @epi
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql =
'DECLARE @wd VARCHAR(4); ' +
'SELECT TOP 1 @wd = WD ' +
'FROM T ' +
'WHERE MRN = ' + Convert(VARCHAR, @mrn) + ';' +
'UPDATE T ' +
'SET WD = @wd ' +
'WHERE MRN = ' + Convert(VARCHAR, @mrn) + ' AND EPI = ''' + @epi + ''''
EXEC(@sql);
FETCH NEXT
FROM @get_rec INTO @mrn, @epi
END
CLOSE @get_rec
DEALLOCATE @get_rec
GO
IF EXISTS (SELECT *
FROM sys.indexes
WHERE name='idxEETEST' AND object_id = OBJECT_ID('T'))
DROP INDEX [idxEETEST] ON [T];
GO
Vielen Dank für Ihre Zeit.
Warum verwenden Sie eine Schleife mit dynamischen SQL für ein Update? Dies könnte als eine einzige Update-Anweisung ohne dynamisches SQL oder Looping umgeschrieben werden. –
Weil ich rosten wie die Hölle und kämpfte um zu sehen, wie ich den ersten Datensatz eines Stapels erhalten konnte, um die gleiche Tabelle ohne Rekursion zu aktualisieren. Jede Hilfe würde sehr erhalten werden. – MoonKnight
Ich folge nicht ganz der Logik dessen, was Sie hier erreichen wollen. Können Sie die Geschäftsregeln erklären? –