Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL 2005 – Verbindungsserver zu Oracle-Abfragen extrem langsam

In Ihrem ersten Beispiel mit der "Punkt"-Notation wird die Client-Cursor-Engine verwendet und die meisten Dinge werden lokal ausgewertet. Wenn Sie aus einer großen Tabelle auswählen und eine WHERE-Klausel verwenden, werden die Datensätze lokal aus der Remote-Datenbank gezogen. Sobald die Daten über den Verbindungsserver gezogen wurden, wird die WHERE-Klausel erst dann lokal angewendet. Oft ist diese Sequenz ein Performance-Hit. Indizes auf der entfernten Datenbank werden grundsätzlich unbrauchbar gemacht.

Wenn Sie alternativ OPENQUERY verwenden, sendet SQL Server die SQL-Anweisung zur Verarbeitung an die Zieldatenbank. Während der Verarbeitung werden alle Indizes für die Tabellen genutzt. Auch die where-Klausel wird auf Oracle-Seite angewendet, bevor das Resultset an SQL Server zurückgesendet wird.

Meiner Erfahrung nach bietet Ihnen OPENQUERY mit Ausnahme der einfachsten Abfragen eine bessere Leistung.

Aus den oben genannten Gründen würde ich empfehlen, OpenQuery für alles zu verwenden.

Einer der Schwachpunkte bei der Verwendung von OpenQuery, auf den Sie möglicherweise bereits gestoßen sind, sind einfache Anführungszeichen. Wenn die SQL-Zeichenfolge, die an die Remote-Datenbank gesendet wird, einfache Anführungszeichen um eine Zeichenfolge oder ein Datumsdatum erfordert, müssen diese maskiert werden. Andernfalls beenden sie versehentlich den SQL-String.

Hier ist eine Vorlage, die ich verwende, wenn ich mit Variablen in einer Openquery-Anweisung an einen Verbindungsserver arbeite, um das Problem mit einfachen Anführungszeichen zu lösen:

DECLARE @UniqueId int 
, @sql varchar(500) 
, @linkedserver varchar(30) 
, @statement varchar(600) 

SET @UniqueId = 2 

SET @linkedserver = 'LINKSERV' 
SET @sql = 'SELECT DummyFunction(''''' + CAST(@UniqueId AS VARCHAR(10))+ ''''') FROM DUAL' 
SET @statement = 'SELECT * FROM OPENQUERY(' + @linkedserver + ', '  
SET @Statement = @Statement + '''' +  @SQL + ''')' 
EXEC(@Statement)