2008-11-28 5 views
0

Я использую инструкцию SQL для удаления записей, существующих в другой базе данных, но это занимает очень много времени.Улучшение производительности скрипта asp, которое занимает 3+ минут для запуска

Есть ли другая альтернатива нижеприведенному коду, которая может быть быстрее? База данных - это доступ.

email_DB.mdb откуда я хочу, чтобы удалить адреса электронной почты, которые существуют на другой базе данных (таблица Newsletter_Subscribers) customers.mdb является другой базой данных (таблица клиенты)

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: попробовал SQL ниже одного из ответов, но я получаю сообщение об ошибке при запуске его:

SQL: DELETE FROM WHERE Newsletter_Subscribers CustID в (выберите CustID из [ "& strDBPath &" Клиенты] .Customers где Subscriber_Email = Email или Subscriber_Email = Эма ilO)

Я получаю «Слишком мало параметров. Ожидаемое 1. «Сообщение об ошибке на строке Выполнить

+0

IIRC, это сообщение может означать, что вы используете имя столбца, который не существует, так что это рассматривая его как параметр. – dkretz 2008-11-29 18:06:48

+0

Предполагается, что существует * между DELETE и FROM – AnonJr 2009-03-09 07:20:07

ответ

0

Я хотел бы использовать ГДЕ Subscriber_Email В (электронная почта, Email0) как ИНЕКЕ

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

я нашел из опыта, что с помощью OR предикат в предложении WHERE может быть вредным с точки зрения производительности, поскольку SQL придется оценивать каждое предложение отдельно, и он может решить игнорировать индексы и использовать сканирование таблицы. Иногда может быть лучше разбить его на два отдельных заявления. (Я должен признать, что я имею в виду с точки зрения SQL Server здесь, но то же самое может относиться к Access)

"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

Предполагая, что есть идентификатор колонка присутствует в таблице Customers, следующие изменения в SQL должны дать более высокую производительность:

» УДАЛИТЬ ИЗ Newsletter_Subscribers WHERE ID IN (выберите ID от [»& strDBPath &„Клиенты] .Customers где Subscriber_Email = Email или Subscriber_Email = EmailO)“

PS. идеальное решение (судя по именам столбцов) будет перепроектировать таблицы и логику кода вставки писем в первую очередь. DS

+0

Да, таблица Customers (customers.mdb) имеет таблицу CustID и Newsletter_Subscribers (email_DB.mdb) в качестве Subscriber_ID. Итак, я должен заменить ID на CustID на вашем SQL? – smartins 2008-11-28 14:58:20

0

Попробуйте добавить Access Querydef и вызовите это.

0

Похоже, что у вас нет указателя в поле subscriber_enail. Это заставляет сканирование таблицы (или несколько). Добавьте индекс в это поле, и вы увидите значительное улучшение.

я бы кодированный запрос

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

Я хотел бы попробовать разделить этот на две отдельные операторы с отдельными соединениями с базами данных.

Сначала введите список адресов электронной почты или идентификаторов в первой базе данных (в виде строки).

Во-вторых, создайте инструкцию WHERE NOT IN и запустите ее во второй базе данных.

Я бы предположил, что это будет намного быстрее, так как ему не нужно взаимодействовать между двумя базами данных. Единственная возможная проблема заключается в том, что в первой базе данных есть тысячи записей, и вы нажимаете максимальную длину строки запроса sql (независимо от того, что есть).

Вот некоторые полезные функции для этого:

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 
Смежные вопросы