Was ist schneller und DB-verträglicher - FIND oder SELECT ?

23/10/2008 - 00:53 von Andy Dorwald | Report spam
Hallo SQL-NG,

ich muss bei rund 10.000 Datensàtzen die ich aus einer Liste importiere,
prüfen, welche von denen bereits in der Datenbank sind.

Nur wenn noch nicht vorhanden, will ich sie importieren.

Nun frage ich mich, was da performanter / optimaler ist, um die bereits
vorhandenen Daten mit den zu importierenden zu überprüfen.

Entweder so:

rs.Open "SELECT ID FROM Tabelle", conn, adOpenForwardOnly, adLockReadOnly

und dann vor jedem der 10.000 Datensàtze abfragen: rs.Find "ID='" & ID &
"'", 0, adSearchForward, adBookmarkFirst

...wenn EOF, dann importiere ich, wenn NOT, dann überspringe ich.

ODER sollte ich besser immer per SELECT fragen? also so:
conn.EXECUTE("SELECT ID FROM Tabelle WHERE ID='" & ID & '").EOF then ...
Satz importieren!

Ich habe versucht es irgendwie zu messen, doch schwanken die Ergebnisse, da
ich sowieso nur eine lokale DB zum testen besitze(!).

Würde mich über eine Antwort freuen
Andy
 

Lesen sie die antworten

#1 Uwe Ricken
23/10/2008 - 07:02 | Warnen spam
Hallo Andy,

das Konzept des SQL Server basiert darauf, mengenorientierte Operationen
schnell abzuarbeiten.
Zum zweiten ist es doch wohl logisch, dass es da am schnellsten ist, wo die
Daten sind, oder?

Ich würde das ganze mittels eines OUTER JOIN machen. Da hast Du beide obigen
Rahmenbedingungen erfüllt.

Beispiel: Aufgrund Deiner Codefragmente gehe ich davon aus, dass Du VB(A)
verwendest.

1. Zunàchst mal eine Stored Procedure für dem Rahmen
CREATE PROC dbo.proc_app_MergeRecords
AS
SET NOCOUNT ON

DECLARE @ReturnValue int

INSERT INTO dbo.tbl_app_Target
SELECT s.*
FROM dbo.tbl_app_Source s LEFT JOIN dbo.tbl_app_Target t
ON (s.PrimaryKey = t.PrimaryKey)
WHERE t.PrimaryKey IS NULL

SET @ReturnValue = @@ROWCOUNT

SET NOCOUNT OFF
GO

2. Nun zu Deinem VB(A)-Code. Am performantesten ist es natürlich, wenn Du
mittels ADO die SP feuerst.
Etwa so:
Dim ReturnValue As Long
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter

Set cmd = New ADODB.Command
With cmd
Set .ActiveConnection = CurrentProject.Connection ' geht aber nur bei
ADP-Datei!
.CommandText = "dbo.proc_app_MergeRecords"
.CommandType = adCmdStoredProc

Set prm = .CreateParameter("ReturnValue", adInteger, adParamReturnValue)
.Parameters.Append prm

.Execute

ReturnValue = Nz(.Parameters("ReturnValue"), 0)
End With

MsgBox "Es wurden " & CStr(ReturnValue) & " Datensàtze importiert..."
Set prm = nothing
Set cmd = Nothing


Nicht viel Code aber sicherlich um ettliches schneller, als Deine Lösung.
Sofern Du nicht mit einer ADP arbeitest, mußt Du natürlich noch ein
Connection-Objekt haben.
Mehr dazu findest Du unter http://www.connectionstrings.com

Entscheidender Unterschied zu Deiner Lösung ist ganz klar, dass die
Operation nun vom Client auf den Server verlagert wurde.
Mehrere wesentliche Vorteile:

- Du musst nicht erst Daten holen, um sie zu verarbeiten
- Du reduzierst die Netzlast, weil 10.000 Anfragen an den Server wegfallen
- Du sparst Rechenzeit des Servers, da er nicht 10.001 Anfragen bearbeiten
muss, sondern nur 1
- Operation wird in wenigen Sekunden ausgeführt
- Daten werden da verarbeitet, wo sie sind.

HTH ;-)


Gruß, Uwe Ricken
MCP for SQL Server 2000 Database Implementation

db-Berater GmbH - 64390 Erzhausen
http://www.db-berater.de
http://www.memberadmin.de
http://www.conferenceadmin.de
____________________________________________________
dbdev: http://www.dbdev.org
FAQ: http://www.donkarl.com/AccessFAQ.htm

Ähnliche fragen