Tabellen in zwei Datenbanken verknüpfen machen Abfrage langsam? ist es besser, db zu partitionieren?

9

Ich habe ein table1In db1und table2In db2auf SQL Server 2008 R2.

Wenn ich eine Auswahlabfrage mache, die beide Tabellen verbindet, ist es sehr langsam, die Ergebnisse zu erhalten.

Eine einfache Abfrage wie

SELECT * 
FROM db1.dbo.table1 t1 
LEFT JOIN db2.dbo.table2 t2 ON t1.k1 = t2.k2

ist manchmal WIRKLICH langsam.

Ich bin mir nicht sicher, ob dies SQL Server gemeinsam ist und "wie eine Regel sein muss", um "nicht zwei Tabellen zu verbinden, die aus verschiedenen Datenbanken stammen".

In diesem Fall ... füge ich dieser Frage hinzu, dass ich eine dieser Datenbank-Binärdaten in einem Feld gespeichert habe und mich gerne von der Hauptdatenbank trennen möchte, um die Größe der Haupttabelle nicht zu erhöhen ... es ist besser, eine Datenbank dafür zu partitionieren ?

Ich habe mit zwei einfachen Tabellen getestet und das Verbinden dieser beiden Tabellen ist immer noch langsam.

Vielen Dank im Voraus für jede Hilfe.

.. Einige Jahre später aktualisieren ... 24-09-18

Stellen Sie sicher, dass die Felder, die Sie verbinden, denselben Typ, dieselbe Größe und dieselbe Sortierung haben.

Beispiel: Eine Eigenschaft ist varchar (255) und eine andere varchar (20) ... das kann ein Problem sein, da die Engine einen Typ in einen anderen umwandeln muss (eine implizite Konvertierung erfolgt) und manchmal schneller ausgeführt wird ... wenn a Wenn eine Neuindizierung oder eine Änderung in der Datenbank auftritt, können Sie sehen, dass der Beginn der Abfrage in einem bestimmten Moment viel länger gedauert hat.

Wenn Sie den Feldtyp nicht so ändern können, dass er in einer der Datenbanken / Tabellen übereinstimmt, versuchen Sie, eine explizite Umwandlung durchzuführen, um festzustellen, ob dies die Abfragegeschwindigkeit verbessert. verwenden cast(fieldname as type(size)) = fieldName2)

FabianSilva
quelle
Haben Sie Indizes für die JOIN-Felder?
Mihai
5
Wenn sich die beiden Tabellen in unterschiedlichen Datenbanken befinden, sich jedoch in derselben Instanz befinden, sollte dies die Leistung nicht wesentlich beeinträchtigen. Das Überprüfen von Berechtigungen in verschiedenen Datenbanken ist nur mit einem Mehraufwand verbunden. Die Hauptgründe für Leistungsprobleme sind normalerweise fehlende Indizes und / oder Sperren / Blockieren.
Lmu92
1
Können Sie erklären, warum Sie zwei Datenbanken benötigen und nicht alle Daten in einer haben?
Ypercubeᵀᴹ
1
Können Sie Ihren tatsächlichen Ausführungsplan veröffentlichen?
Lmu92
1
@FabianSilva: Das ist überhaupt keine Erklärung. Bitte geben Sie eine bessere Beschreibung der Geschäftsanforderungen an, für die separate Datenbanken erforderlich sind.
Pieter Geerkens

Antworten:

23

Sie haben hier eine Reihe verschiedener Fragen, also lassen Sie uns sie einzeln aufteilen.

F: Wenn ich mit der obigen Abfrage zwei Tabellen in derselben Datenbank verbinde, warum ist es dann langsam?

A: Für den Anfang verwenden Sie keine WHERE-Klausel, daher muss SQL Server die vollständige Ergebnismenge erstellen und beide Tabellen zusammenführen. Wenn Sie nur eine Teilmenge der Daten benötigen, sollten Sie eine WHERE-Klausel verwenden, um nur die benötigten Daten abzurufen.

Beachten Sie anschließend, dass Sie einen LEFT OUTER JOIN verwenden. Dies teilt SQL Server mit: "Nicht alle table1-Datensätze haben übereinstimmende Datensätze in table2." Das ist völlig in Ordnung, wenn es wahr ist - aber wenn Sie wissen, dass alle t1-Datensätze mindestens einen t2-Datensatz haben, verwenden Sie stattdessen einen INNER JOIN.

Als Nächstes beginnt die Indizierung. Abhängig von der Breite der Tabellen und der Anzahl der Felder möchten Sie möglicherweise Indizes für die Felder hinzufügen, die Sie für den Join verwenden. Um gute Ratschläge dazu zu erhalten, veröffentlichen Sie am besten den tatsächlichen Ausführungsplan, mit dem Sie arbeiten.

F: Wenn sich die Tabellen in verschiedenen Datenbanken auf demselben SQL Server befinden, ändert sich dadurch etwas?

A: Nein. Es gibt einige interessante Fallstricke in Bezug auf Standardisolationsstufen in verschiedenen Datenbanken, aber zum größten Teil sollten Ihre Abfragen dieselben Ausführungspläne und -geschwindigkeiten erzeugen.

F: Sollte ich die Tabellenpartitionierung verwenden, um dies zu beschleunigen?

A: Sie haben die Datenbankpartitionierung erwähnt, aber in SQL Server gibt es so etwas nicht - ich vermute, Sie haben die Tabellenpartitionierung gemeint. Im Allgemeinen, nein, ich würde nicht zu Änderungen am Datenbankdesign springen, um einen Join schneller zu machen. Beginnen Sie mit den Grundlagen - dem Verständnis der SQL Server-Ausführungspläne - und nehmen Sie nur Änderungen am Datenbankdesign vor, um Probleme zu lösen, die Sie mit Dingen wie Indizes nicht beheben können.

Brent Ozar
quelle
11
Insbesondere wenn Sie nicht alle Spalten benötigen (und zumindest die Verknüpfungsspalte redundant ist), beenden Sie die VerwendungSELECT * .
Aaron Bertrand
danke @AaronBertrand Ich habe zuvor ein "Select *" in einer Ansicht und wenn eine der Tabellen geändert wurde, die die Ansicht verwenden, hat das "select *" fehlerhafte Tabellenspalten abgerufen und muss die Tabelle ändern und erneut speichern, damit sie funktioniert. Im Allgemeinen ist select * wirklich ein Monster, das nicht existieren muss. Ich habe nur "select *" als generisches Beispiel für die Verknüpfung von zwei Tabellen mit zwei Datenbankdaten angegeben. Nicht mehr als das.
FabianSilva
@FabianSilva Ja, ich spreche in dem von mir verlinkten Beitrag über genau dieses Szenario .
Aaron Bertrand
Die zweite Antwort war, was ich wissen muss, nicht sicher, warum es in DIESEM Fall langsam war, diese Datenbank zu verbinden ... aber zumindest kann ich wissen, dass ich nichts falsch gemacht habe, um Tabellen auf verschiedenen Datenbanken desselben Servers zu verbinden.
FabianSilva