2017-06-05 4 views
0

Ich habe eine SQL-Abfrage, die Analysetabellen erstellt, die SELECT INTO-Anweisungen aus aufgefüllten Staging-Tabellen verwenden. Dieser Teil geht ziemlich glatt, aber wenn ich versuche, Felder an die Analysetabellen, voneinander oder von den ursprünglichen Staging-Tabellen anzufügen, laufen die UPDATE-Abfragen für HOURS.SQL Server-Update-Abfragen, die zu lange dauern

Ich fühle diese Laufzeit ist nicht gerechtfertigt, da die meisten Datensätze pro Tabelle 200K ist. Ich habe das Gefühl, dass dies ein Problem mit meiner Protokolldateiverwaltung oder die Tatsache, dass ich keine Indizes für eine dieser Tabellen habe. Ich habe gezögert, Indizes zu bauen, weil ich weiß, wenn sie hastig erledigt werden, können sie tatsächlich mehr Probleme verursachen. Für diese Tabellen gibt es keine Trigger.

Ich versuche, einen Ansatz zu finden, so dass diese Abfrage konsistent ausgeführt wird. In der Vergangenheit hat es unter 1 Stunde gelaufen (was immer noch wahrscheinlich zu lang ist), aber heute hat es zum Beispiel mehr als 3 Stunden gedauert.

Ich habe die Protokolldatei bereits geändert, um 50% statt 10% automatisch zu vergrößern, um eine unbegrenzte MAXSIZE zu haben, habe ich den DB-Wiederherstellungsmodus auf SIMPLE gesetzt, und ich habe die Protokolldatei manuell verkleinert. Nichts davon hilft.

Ich weiß, dass TABELLE SCANS sind eine Quelle der Verzögerung in großen Abfragen, ist also die Lösung hier Indizes für alle Felder zu erstellen, die ich in meinen LINKEN JOINs unten dargestellt verwende? Diese Snippets sind genaue Beispiele für die Frage, wo die Abfrage verzögert ist. Ich habe Transparenz darin, weil ich die Ausführung des Skripts im LIVE QUERY STATISTICS-Fenster befolge.

UPDATE a 
SET a.[Account ID] = b.[Account ID] 
FROM SFAX.dbo.Leads as a 
left join SFAX.dbo.Accts as b on a.[Company Account] = b.[Account Name] 
WHERE a.[Account ID] IS NULL; 

-- Link by website2 
UPDATE a 
SET a.[Account ID] = b.[Account ID] 
FROM SFAX.dbo.Leads as a 
left join SFAX.dbo.Accts as b on a.url2 = b.Website2 
WHERE a.[Account ID] IS NULL; 
-- 
UPDATE a 
SET a.[SFDC Account Name] = b.[Account Name] 
FROM SFAX.dbo.Leads as a 
left join SFAX.dbo.Accts as b on 
a.[Account ID] = b.[Account ID] 
WHERE a.[Account ID] IS NOT NULL; 

UPDATE a 
SET a.ConvertedFlag = b.[Lead ID] 
FROM SFAX.dbo.WhoAnalysis1 as a 
LEFT JOIN SFAX.dbo.Contacts as b ON a.WhoId = b.[Contact ID]; 
+4

Bitte geben Sie keine Leerzeichen in die Spaltennamen ein – Hogan

+2

Sie sollten Indizes erstellen – Hogan

+1

Sie nehmen nicht an, dass die 'CREATE TABLE'-Anweisungen auch nur das geringste Interesse haben könnten? –

Antwort

3

Hinweis: In den Kommentaren über Sie äußern Zweifel. Dies ist leicht zu testen - brechen Sie Ihr Skript vor den Updates in zwei Teile - führen Sie den ersten Teil - dann führen Sie ein Update und Zeit es. Dann machen Sie Indizes für dieses eine Update. Führen Sie es erneut aus. Wie viele Größenordnungen schneller ist es?

Haben Sie keine Angst vor Indizes, wenn Sie mit SQL arbeiten - lieben Sie Ihre Indizes. Erstellen von Indizes für

SFAX.dbo.Leads.[Company Account], [Account ID] 
SFAX.dbo.Accts.[Account Name] 

SFAX.dbo.Leads.url2, [Account ID] 
SFAX.dbo.Accts.Website2 

SFAX.dbo.Leads.[Account ID] 
SFAX.dbo.Accts.[Account ID] 

SFAX.dbo.WhoAnalysis1.WhoID 
SFAX.dbo.Contacts.[Contact ID] 

Aber denken Sie daran - wenn Sie viele Datensätze in der Datenbank ändert dies durch die Geschwindigkeit des I/O

+0

Würde es irgendetwas im Ausführungsplan herausstehen, um als Beweis zu dienen, dass diese Indizes tatsächlich benötigt werden? Würden nicht die Nullwerte im Index für [Konto-ID] zusätzliche Aufmerksamkeit erfordern, wie dies [hier] vorgeschlagen wurde (https://stackoverflow.com/a/20687291/578411)? – rene

+0

Ich glaube nicht, dass ich jemals Aaron Bertrand falsch liegen gesehen habe, aber das scheint mir im Bereich der Optimierung zu liegen. Wir haben eine Abfrage, die Stunden dauert und Sekunden dauern sollte - zuerst auf die einfache und dann bei Bedarf optimieren. Die Tatsache, dass der Ausführungsplan Scans enthält, zeigt, dass Indizes helfen würden. – Hogan

+0

@Hogan versucht, Ihren Vorschlag auf mein gesamtes Skript zu skalieren, und ich möchte nur auf etwas klar sein ... Wenn ich die Indizes erstelle, schlägst du vor, dass ich es nur auf den Feldern erzeuge, die in den JOINs verwendet werden? Oder sollte ich einen Index für das Feld erstellen, das in den JOINs UND das Feld verwendet wird, das von der UPDATE-Anweisung festgelegt wird? – hansolo

1

Unten eingeschränkt sein könnte hat eine Menge Unsinn Arbeit zu tun - Tu es nicht.

UPDATE a 
SET a.[Account ID] = b.[Account ID] 
FROM SFAX.dbo.Leads as a 
left join SFAX.dbo.Accts as b on a.[Company Account] = b.[Account Name] 
WHERE a.[Account ID] IS NULL; 

Wenn in b keine Übereinstimmung vorhanden ist, wird [a.Account ID] auf null gesetzt. Aber Sie wählen nur diese Zeilen in einem, wo die Spalte NULL ist. SO TUN SIE DAS NICHT - Ihre linke Verbindung ist sinnlose zusätzliche Arbeit. Ändern Sie es in einen inneren Join. Wird das erheblich helfen? Ich kann es nicht sagen, ohne die Eigenschaften Ihrer Daten zu kennen.

+0

wow ... das ist subtil - es wird die Geschwindigkeit der Abfrage nicht ändern, es sei denn, es gibt einen Index, aber einen guten Punkt. – Hogan

+0

das ist ein toller Vorschlag, an den ich nie gedacht habe. Der innere Join würde helfen, überflüssige Anweisungen zu eliminieren. – hansolo

Verwandte Themen