2017-05-08 4 views
3

ich den Code unten haben ...Verbesserung der Leistung SP

UPDATE Sales 
    SET MappingOrderID = CAST ([dbo].[fRemoveNonNumericCharacters] (ltrim(rtrim(ActualOrderNumber))) AS INT) 
    FROM Sales 
    where isnumeric(ActualOrderNumber) = 1 
    and ActualOrderNumber not like '%.%' 
    and len(ActualOrderNumber) < 10 
    and MappingOrderID is null 
    and ActualOrderNumber is not null 
    and ltrim(rtrim(ActualOrderNumber)) in (select ltrim(rtrim(OrderID)) from dbo.Orders) 

Die beteiligten Spalten sind:

aus dem Verkauf: MappingOrderId INT ActualOrderNumber NVARCHAR (10)

Von Aufträge: OrderId INT

Dies ist Legacy-Code, ich bin der DBA, ich weiß nicht, warum er/sie T verwendet so vielen Rand ... Das Skript dauert 9 Minuten zu laufen, und hat idealerweise häufig ausgeführt werden ...

ich dies auch im Ausführungsplan:

  • CONVERT_IMPLICIT (varchar (12), [Datamart] . [DBO]. [Orders]. [OrderID],

    0)
  • CONVERT_IMPLICIT (VARCHAR (20), [Datamart]. [DBO]. [Sales]. [ActualOrderNumber], 0)

  • Typkonvertierung in Ausdruck (CONVERT_IMPLICIT (varchar (20), [DataMart]. [Dbo]. [Verkauf]. [ActualOrderNumber], 0)) kann "CardinalityEstimate" in der Abfrageplanauswahl beeinflussen, Typkonvertierung in Ausdruck (CONVERT_IMPLICIT (varchar (12), [Datamart]. [dbo]. [Aufträge]. [OrderID], 0)) kann "CardinalityEstimate" im Abfrageplan beeinflussen Wahl

Für das, was ich fühle ...

Es Updates MappingOrderId (int) durch ActualOrderNumber (varchar) Gießen ... Es nur aktualisieren, wenn ActualOrderNumber in Aufträge existiert ...

Ich versuche ein paar Modifikationen; aber der varchar ActualOrderNumber hat Werte wie 3545427103, und wenn ich versuche, alles zu entfernen, wie:

and len(ActualOrderNumber) < 10 

Es bricht ...

Mein Gesamtziel ist es, diesen Prozess zu machen die effizienteste möglich; stellt die Daten an der Quelle die einzig wahre Lösung dar?

Ich habe viele der Vorschläge implementiert und es ging bis zu einer Minute. Vielen Dank! Aber was ich nicht verstehe, ist dies:

Bevor mit dem hässlichen Code, den ich hatte: enter image description here

Jetzt habe ich mehr liest ... und es dauert Sekunden zu laufen ... wie ist das möglich? enter image description here

+0

LIKE ist auch sehr teuer. Es gibt sicherlich Möglichkeiten, diese Abfrage zu verbessern, wenn Sie die Logik kennen. Ist das ein Scheck für einen Dollar-Wert im Bestellnummernfeld? Das könnte in CONTAINS geändert werden. Was ist los, wenn nur die Bestellnummern mit einer Länge von weniger als 10 zurückgegeben werden? –

+1

Wenn Sie die Gelegenheit haben, fügen Sie beiden Tabellen eine Spalte hinzu, die die gesäuberte Bestellnummer enthält, füllen Sie sie auf und indizieren Sie sie. Die Gesamtzeit kann mindestens neun Minuten betragen. Sie können auch einen Vorteil sehen, wenn Sie das letzte 'IN' in ein' exist' ändern, aber den Abfrageplan zwischen den Änderungen überprüfen. –

+0

Oh, und Sie haben auch eine UDF dort, die Dinge verlangsamen könnte. Der Abfrageplan sollte Ihnen eine Idee geben. Um herauszufinden, ob das CardinalityEstimate tatsächlich betroffen ist, vergleichen Sie tatsächliche und geschätzte Pläne und sehen, ob sich die Anzahl der Zeilen in der gleichen Umgebung befindet. –

Antwort

1
UPDATE Sales 
SET MappingOrderID = CAST (ltrim(rtrim(ActualOrderNumber)) AS INT) 
FROM Sales S 
inner join dbo.Orders O on ltrim(rtrim(O.OrderID))=ltrim(rtrim(s.ActualOrderNumber)) 
where isnumeric(ActualOrderNumber) = 1 
and ActualOrderNumber not like '%.%' 
and len(ActualOrderNumber) < 10 
and MappingOrderID is null 

Änderungen

1. Entfernte Funktion "fRemoveNonNumericCharacters"

  • Wie Sie IsNumeric einchecken, wo Klausel, gibt es keine Notwendigkeit, diese Funktion zu nutzen.

2. Beigetreten Umsatz und Auftragseingang Tabelle

  • wenn Sie Aufträge Tabelle in where-Klausel verwenden, wie Sie erwähnt haben, dann für jede Reihe von Verkaufstisch wird komplett Orders-Tabelle wiedergegeben werden.
  • Um diesen Prozess zu reduzieren, habe ich hinzugefügt beizutreten.

3. entfernt ActualOrderNumeric nicht null ist

  • Wie Sie überprüfen IsNumeric in where-Klausel, gibt es keine Notwendigkeit, diese Bedingung zu verwenden. Denn für Null gibt isnumeric 0 zurück.
+0

wahrscheinlich könnte hinzufügen "und ENTHÄLT (ActualOrderNumber, '')" Welche sollte effizienter sein als die NOT LIKE-Klausel. Hoffentlich sind diese Spalten indiziert. –

Verwandte Themen