2010-08-26 6 views
6

Sur mon serveur SQL 2005, j'ai un serveur lié se connectant à Oracle via le fournisseur OraOLEDB.Oracle.SQL 2005 - Serveur lié aux requêtes Oracle extrêmement lent

Si je lance une requête par l'identifiant 4 partie comme ceci:

SELECT * FROM [SERVER]...[TABLE] WHERE COLUMN = 12345 

Il faut plus d'une minute. Si je cours la même requête comme ceci:

SELECT * FROM OPENQUERY(SERVER, 'SELECT * FROM TABLE WHERE COLUMN = 12345') 

Il se termine instantanément. Y at-il un paramètre qui me manque quelque part pour que la première requête s'exécute dans une période de temps décente? Ou suis-je coincé en utilisant openquery?

Répondre

10

Dans votre premier exemple utilisant la notation "point", le moteur de curseur client est utilisé et la plupart des choses sont évaluées localement. Si vous sélectionnez une grande table et utilisez une clause WHERE, les enregistrements seront extraits localement à partir de la base de données distante. Une fois que les données ont été tirées à travers le serveur lié, seulement alors la clause WHERE est appliquée localement. Souvent, cette séquence est un coup de performance. Les index sur la base de données distante sont essentiellement rendus inutiles.

Alternativement lorsque vous utilisez OPENQUERY, SQL Server envoie l'instruction SQL à la base de données cible pour traitement. Pendant le traitement, tous les index sur les tables sont exploités. La clause where est également appliquée du côté Oracle avant de renvoyer le jeu de résultats à SQL Server. Dans mon expérience, à l'exception de la plus simple des requêtes, OPENQUERY va vous donner de meilleures performances.

Je recommanderais d'utiliser OpenQuery pour tout pour les raisons ci-dessus.

L'un des points douloureux lors de l'utilisation d'OpenQuery que vous avez peut-être déjà rencontré est un guillemet simple. Si la chaîne sql envoyée à la base de données distante requiert des guillemets simples autour d'une chaîne ou d'une date, ils doivent être échappés. Sinon, ils terminent par inadvertance la chaîne sql.

Voici un modèle que j'utilise chaque fois que je fais face à des variables dans une instruction OPENQUERY à un serveur lié à prendre en charge le problème de guillemet simple:

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)