SQL Server INNER REMOTE JOIN gibt mehr Zeilen als INNER JOIN zurück

7

Ich versuche, einige Zeilen aus einer Remote-Ansicht mit einer lokalen Tabelle zu verknüpfen. Die Ansicht hat ungefähr 300 Millionen Zeilen, daher möchte ich den REMOTE-Abfragehinweis verwenden, damit nicht alle 3 Millionen Zeilen auf meinen Computer übertragen werden müssen.

SELECT R.Something, L.ID, L.Something
FROM [dbo].[LocalTable] L
INNER JOIN (
    SELECT TOP 100 Something, L_ID FROM [RemoteServer].[RemoteDB].[dbo].[RemoteTable]
    ) R
ON L.ID = R.L_ID

Dies gibt erwartungsgemäß 100 Zeilen zurück und benötigt im Grunde keine Zeit, wie ich erwartet hatte.

Jedoch,

SELECT R.Something, L.ID, L.Something
FROM [dbo].[LocalTable] L
INNER REMOTE JOIN (
    SELECT TOP 100 Something, L_ID FROM [RemoteServer].[RemoteDB].[dbo].[RemoteTable]
    ) R
ON L.ID = R.L_ID

beginnt Tausende von Zeilen zurückzugeben. Ich habe es nach ein paar Sekunden beendet, aber es waren Zehntausende.

Wie kann ein Abfragehinweis meine Ergebnismenge ändern?

xyzzy
quelle
1) Wie groß ist die lokale Tabelle? 1b) Sind Sie sicher, dass Sie auf dem richtigen Server sind? 2) Wie ist die Beziehung; 1-1, 1-viele, viele-viele? 3) Wie in einer der Antworten ausgeführt, ist TOPohne ORDER BYbedeutungslos, aber es ist nicht viel besser, die obersten n Reihen zu ergreifen, wenn sie nicht tatsächlich in dem Satz sind, an dem Sie interessiert sind - was war der Grund, die Top 100 zu ergreifen Zeilen hier? 4)
Uhrwerk-Muse

Antworten:

18

TOP 100Auf keinen ORDER BYFall ist es unbestimmt, welche 100 Zeilen aus der entfernten Tabelle am Join teilnehmen. Dies ist vom Ausführungsplan abhängig und kann variieren.

Wenn es sich um eine Eins-zu-Viele-Beziehung handelt, kann es vorkommen, dass ein Stapel mit 100 Zeilen auf der anderen Seite des Joins mehr Übereinstimmungen aufweist als ein anderer Stapel mit 100 Zeilen.

Sie sollten eine ORDER BY(innerhalb der abgeleiteten Tabelle) für eine eindeutige Spalte oder Kombination von Spalten angeben , um deterministische Ergebnisse sicherzustellen.

Martin Smith
quelle
TOPohne ein ORDER BYist bedeutungslos, ja, aber ich würde TOPvor der Join-Bedingung (welche relevanten Zeilen!?) sowieso als ziemlich bedeutungslos betrachten. Sie müssen in der Lage sein, dieselben Suchkriterien zu erhalten, was wahrscheinlich einer Verletzung der Normalisierung gleichkommt.
Uhrwerk-Muse
@ Clockwork-Muse - Überhaupt nicht. Es wäre durchaus möglich, die neuesten 100 Zeilen aus der entfernten Tabelle ( TOP 100 ... FROM RemoteTable ORDER BY DateInserted DESC) und die zugehörigen Details aus der lokalen Tabelle zu erhalten. Zum Beispiel ist es nicht bedeutungslos, die letzten 100 Auftragsköpfe und ihre Werbebuchungen anzufordern. (Obwohl es unwahrscheinlich ist, dass dies auf Server aufgeteilt wird)
Martin Smith
1

Sie können versuchen, die Remote-Abfrage zur Remote-Ausführung zu zwingen:

SELECT R.Something, L.ID, L.Something
FROM [dbo].[LocalTable] L
INNER JOIN (
        SELECT TOP 100 Something, L_ID 
        FROM OPENQUERY([RemoteServer], 'SELECT Something, L_ID
                                        FROM [RemoteDB].[dbo].[RemoteTable]'
                      )
               ) R
ON L.ID = R.L_ID

Oder (wenn der 100-Limiter in der Remote-Abfrage enthalten sein soll):

SELECT R.Something, L.ID, L.Something
FROM [dbo].[LocalTable] L
INNER JOIN (
        SELECT Something, L_ID 
        FROM OPENQUERY([RemoteServer], 'SELECT TOP 100 Something, L_ID
                                        FROM [RemoteDB].[dbo].[RemoteTable]'
                      )
               ) R
ON L.ID = R.L_ID
MguerraTorres
quelle