Tja, das liegt an der Art, wie ich mit den Command-Objekten bzw. Recordsets umgehe.

Wenn du viele identische Select's verwendest und nur die Where-Klausel zu ändern hast, verwende Parameter-Marker !
So benötigst du ggf. nur 1 Command-Objekt pro Abfrage-Typ.
Beispiel: "select .... where feld1=? and feld2=? ....". Jedes "?" ergibt automatisch eine Parameterobjekt, dass vor der Execute-Methode nur gefüllt werden braucht.

Wenn die Daten eines Recordset's nicht mehr benötigt werden, so sollte die Close-Methode verwendet werden und das Objekt gezielt zerstört werden (C++: delete/VB: Nothing).
Das selbe gilt auch bei anderen SQL's:
"insert into myfile (feld1, feld2, ...) values (?, ?, ...)"
"delete from myfile where feld1=? and feld2=? ..."
"call myprocedure parm(?, ?, ..."
usw.

Unter .Net werden neuerdings Resourcen über eine Garbage-Collection verwaltet, und wenn Zeit ist, diese aufgeräumt.
Erstellst du immer ein neues Command-/Recordset-Objekt (bzw. Reader-Objekt), heißt das nicht, dass automatisch alle Resourcen freigegeben werden.
Beispiel:
Im VB6 wurde mit "set myrcd = new adodb.recordset" das vorherige Objekt zerstört und das neue angelegt.
Im .NET wird mit "myrcd = new Recordset()" das alte Objekt in die Garbage-Collection geschickt und ein neues erstellt.
Also vorher "if not myrcd is nothing then set myrcd=nothing" bzw. das Äquivalent dazu.