2008-11-28 6 views
0

J'utilise une instruction SQL pour supprimer les enregistrements qui existent sur une autre base de données, mais cela prend beaucoup de temps.Amélioration des performances du script ASP qui prend plus de 3 minutes

Existe-t-il une autre alternative au code ci-dessous qui peut être plus rapide? La base de données est Access.

email_DB.mdb est d'où je veux supprimer les adresses e-mail qui existent sur l'autre base de données (de Newsletter_Subscribers de table) customers.mdb est l'autre base de données (clients de table)

SQLRemoveDupes = "DELETE FROM Newsletter_Subscribers WHERE EXISTS (select * from [" & strDBPath & "Customers].Customers " _ 
     & "where Subscriber_Email = Email or Subscriber_Email = EmailO)" 

NewsletterConn = "Driver={Microsoft Access Driver (*.mdb)};DBQ=" & strDBPath & "email_DB.mdb" 

Set MM_editCmd = Server.CreateObject("ADODB.Command") 
MM_editCmd.ActiveConnection = NewsletterConn 
MM_editCmd.CommandText = SQLRemoveDupes 
MM_editCmd.Execute 
MM_editCmd.ActiveConnection.Close 
Set MM_editCmd = Nothing 

EDIT: J'ai essayé le SQL ci-dessous de l'une des réponses, mais je continue à obtenir une erreur lors de l'exécuter:

SQL: SUPPRIMER dE Newsletter_Subscribers oU eN CustID (sélectionnez CustID de [ « & strDBPath & » clients] .Customers où Subscriber_Email = E-mail ou Subscriber_Email = Ema ilO)

Je reçois un "trop ​​peu de paramètres. Attendu 1. "message d'erreur sur la ligne Exécuter

+0

IIRC, ce message peut signifier que vous utilisez un nom de colonne qui n'existe pas, il est donc le traiter comme un paramètre. – dkretz

+0

Il doit y avoir un * entre DELETE et FROM – AnonJr

Répondre

0

J'utiliser OÙ Subscriber_Email IN (E-mail, Email0) comme la clause WHERE

SQLRemoveDupes = "DELETE FROM Newsletter_Subscribers WHERE EXISTS " & _ 
(select * from [" & strDBPath & "Customers].Customers where Subscriber_Email IN (Email, EmailO)" 

j'ai trouvé de l'expérience que l'utilisation d'un OU Le prédicat dans une clause WHERE peut être préjudiciable en termes de performances car SQL devra évaluer chaque clause séparément et décider d'ignorer les index et d'utiliser une analyse de table. Parfois, il peut être préférable de le diviser en deux déclarations distinctes. (Je dois admettre que je pense en termes de SQL Server ici, mais le même peut demander à accès)

"DELETE FROM Newsletter_Subscribers WHERE EXISTS " & _ 
    (select * from [" & strDBPath & "Customers].Customers where Subscriber_Email = Email)" 

"DELETE FROM Newsletter_Subscribers WHERE EXISTS " & _ 
    (select * from [" & strDBPath & "Customers].Customers where Subscriber_Email = EmailO)" 
0

En supposant qu'il ya une actuelle colonne ID dans la table des clients, la modification suivante dans SQL devrait donner de meilleures performances:

" DELETE FROM Newsletter_Subscribers WHERE ID IN (sélectionnez ID de [ » & strDBPath & "les clients] .Customers où Subscriber_Email = E-mail ou Subscriber_Email = EmailO)"

PS. La solution idéale (à en juger par les noms de colonnes) serait de redessiner les tables et la logique de code d'insertion des e-mails en premier lieu DS

+0

Oui, la table Customers (clients.mdb) a une table CustID et Newsletter_Subscribers (email_DB.mdb) en tant que Subscriber_ID. Donc, je devrais remplacer l'ID avec CustID sur votre SQL? – smartins

+0

Juste essayé le sql suivant mais je reçois un "trop ​​peu de paramètres. message d'erreur sur la ligne Execute. SQL: SUPPRIMER FROM Newsletter_Subscribers O WH CustID IN (sélectionnez CustID de ["& strDBPath &" Clients] .Customers où Subscriber_Email = Email ou Subscriber_Email = EmailO) – smartins

0

Essayez d'ajouter un Access Querydef et appelez-le.

0

Il semble que vous n'ayez pas d'index dans le champ subscriber_enail. Cela force une analyse de table (ou plusieurs). Ajouter un index sur ce champ et vous devriez voir une amélioration significative.

J'ai codé la requête

DELETE FROM Newsletter_Subscribers where (Subscriber_Email = Email or Subscriber_Email = EMail0) 
+0

Subscriber_Email est en effet indexé (Oui (pas de doublons)). Votre requête ne semble pas prendre en considération que les tables sont sur deux fichiers de base de données séparés (mdb). – smartins

+0

Depuis que vous avez mentionné l'index, j'ai fait quelques expérimentations et j'ai supprimé "OR Subscriber_Email = EMailO" du SQL. Il a terminé en moins d'une seconde. Une idée de pourquoi cela pourrait être? EmailO est également indexé (Duplicates OK). – smartins

+0

vous pouvez lier la table des clients mdb à l'email mdb. Ensuite, la table regarde, et agit, comme si elle faisait partie de la base de données email. – Matthew

0

Je voudrais essayer cela en deux division états distincts avec des connexions de base de données distinctes.

Tout d'abord, récupérez la liste des adresses e-mail ou des ID dans la première base de données (sous forme de chaîne).

Ensuite, construisez une instruction WHERE NOT IN et exécutez-la sur la deuxième base de données.

J'imagine que ce serait beaucoup plus rapide car il ne doit pas interopérer entre les deux bases de données. Le seul problème possible serait s'il y a des milliers d'enregistrements dans la première base de données et que vous atteignez la longueur maximale d'une chaîne de requête sql (quelle qu'elle soit).

Voici quelques fonctions utiles pour cela:

function GetDelimitedRecordString(sql, recordDelimiter) 
    dim rs, str 
    set rs = db.execute(sql) 
    if rs.eof then 
     str = "" 
    else 
     str = rs.GetString(,,,recordDelimiter) 
     str = mid(str, 1, len(str)-len(recordDelimiter)) 
    end if 
    rs.close 
    set rs = nothing 
    GetDelimitedRecordString = str 
end function 

function FmtSqlList(commaDelimitedStringOrArray) 
    ' converts a string of the format "red, yellow, blue" to "'red', 'yellow', 'blue'" 
    ' useful for taking input from an html form post (eg a multi-select box or checkbox group) and using it in a SQL WHERE IN clause 
    ' prevents sql injection 
    dim result:result = "" 
    dim arr, str 
    if isArray(commaDelimitedStringOrArray) then 
     arr = commaDelimitedStringOrArray 
    else 
     arr = split(commaDelimitedStringOrArray, ",") 
    end if 
    for each str in arr 
     if result<>"" then result = result & ", " 
     result = result & "'" & trim(replace(str&"","'","''")) & "'" 
    next 
    FmtSqlList = result 
end function 
Questions connexes