2010-11-18 11 views
7

Anschluss habe ich diese Abfrage bekamlangsame Abfrage, wenn auf Verbindungsserver

UPDATE linkeddb...table SET field1 = 'Y' WHERE column1 = '1234'

Dieser Vorgang dauert 23 Sekunden eine Zeile

auszuwählen und zu aktualisieren Aber wenn ich Openquery verwenden (was ich nicht tun will) dann dauert es nur eine halbe Sekunde.

Der Grund, warum ich OpenQuery nicht verwenden möchte, ist, dass ich Parameter zu meiner Abfrage sicher hinzufügen und vor SQL-Injektionen sicher sein kann.

Kennt jemand irgendeinen Grund dafür, dass es so langsam läuft?

+0

Irgendwelche Hinweise aus dem Abfrageausführungsplan?Oder Sie könnten SQL Profiler einrichten, um die Datenbank zu überwachen und zu sehen, was openquery anders macht. – Rup

Antwort

8

Hier ist ein Gedanke als Alternative. Erstellen Sie eine gespeicherte Prozedur auf dem Remote-Server, um die Aktualisierung durchzuführen, und rufen Sie dann diese Prozedur von Ihrer lokalen Instanz auf.

/* On remote server */ 
create procedure UpdateTable 
    @field1 char(1), 
    @column1 varchar(50) 
as 
    update table 
     set field1 = @field1 
     where column1 = @column1 
go 

/* On local server */ 
exec linkeddb...UpdateTable @field1 = 'Y', @column1 = '1234' 
+0

@Joe - ist eine gespeicherte Prozedur im Grunde nur ein Funktion/Methode für eine Datenbank? – orokusaki

+0

@orokusaki: Ja, man kann es sich so vorstellen. –

+0

@Joe Dies wird nur etwas schneller ausgeführt, da die Analyse und die Kompilierzeit entfallen. @orokusaki Es ist immer noch besser als Ihre Methode, da es die Datenbank vor sql-Injektion schützt. Sie können Berechtigungen auch so festlegen, dass der Benutzer die Tabelle nicht direkt aktualisieren kann, sondern nur über den SP. – stevenrcfox

2

Ist Primärschlüssel Spalte1? Wahrscheinlich nicht. Versuchen Sie, Datensätze für die Aktualisierung mit dem Primärschlüssel auszuwählen (wobei PK_field = xxx), andernfalls (manchmal?) Werden alle Datensätze gelesen, um nach PK zu suchen, damit Datensätze aktualisiert werden können.

+0

Ich bin ziemlich sicher, dass Spalte1 ist der Primärschlüssel, aber mit Blick auf den Ausführungsplan in SQL Query Analyzer zeigt, dass die Remote-Scan dauert am längsten, so scheint es, dass es alle 40.000 Datensätze durchläuft. –

+2

Hmm, wenn Ihr PK (n) varchar ist, dann haben Sie vielleicht ein Kollationsproblem (ich meine, dass SQL keinen solchen Index verwendet, weil es Kollation oder so nicht kennt). Ich habe jedoch keine Erfahrung mit nicht ganzzahligen PK-Feldern. – Arvo

+0

@Jamie, ich zweite Arvo Theorie der Kollation ist ein potenzielles Problem – stevenrcfox

1

Ist Spalte1 ein Varcharfeld? Ist das der Grund, warum Sie den Wert 1234 mit einfachen Anführungszeichen umgeben? Oder ist das nur ein Tippfehler in deiner Frage?

+0

Wenn ich die Abfrage in Query Analyzer ohne die Anführungszeichen ausführen, bekomme ich einen Fehler und ich glaube, Spalte1 ist ein Varchar-Feld –

4

Wenn Sie sich für die warum, ist hier eine Möglichkeit von Linchi Shea's Blog suchen:

So erstellen Sie die besten Abfrage-Pläne, wenn Sie auf einer verknüpften Server eine Tabelle verwenden, die Der Abfrageprozessor muss Datenverteilungsstatistiken vom verbundenen Server haben. Benutzer, die Berechtigungen für alle Spalten der Tabelle begrenzt haben möglicherweise nicht ausreichend Berechtigungen für alle nützlichen Statistiken zu erhalten, und könnte aless effiziente Abfrage-Plan und Erfahrung schlechte Leistung erhalten. Wenn die verknüpfte eine Instanz von SQL Server serveris, um alle verfügbaren Statistiken erhalten, die Benutzer muss die Tabelle besitzen oder Mitglied der festen Serverrolle Sysadmin sein, die db_ownerfixed Datenbankrolle oder die db_ddladmin festen Datenbankrolle auf dem linkedserver.

(Aufgrund von Linchis Beitrag wurde diese Klarstellung zur neuesten BooksOnline SQL-Dokumentation hinzugefügt).

Mit anderen Worten, wenn der Verbindungsserver mit einem Benutzer eingerichtet wurde, der über eingeschränkte Berechtigungen verfügt, kann SQL keine genauen Statistiken für die Tabelle abrufen und wählt möglicherweise eine schlechte Methode zum Ausführen einer Abfrage einschließlich des Abrufens aller Zeilen aus.

Hier ist ein related SO question über die Leistung der Verbindungsserverabfrage. Ihre Schlussfolgerung war: Verwenden Sie OpenQuery für die beste Leistung.

Update: einige additional excellent posts über Linked Server-Leistung von Linchis Blog.