Улучшение производительности asp-скрипта, выполнение которого занимает более 3 минут - PullRequest
0 голосов
/ 28 ноября 2008

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

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

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

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

РЕДАКТИРОВАТЬ: попробовал приведенный ниже SQL из одного из ответов, но я продолжаю получать ошибку при запуске:

SQL: УДАЛИТЬ ИЗ Newsletter_Subscribeers ГДЕ CustID IN (выберите CustID из ["& strDBPath &" Customers]. Клиенты, где Subscriber_Email = Email или Subscriber_Email = EmailO)

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

Ответы [ 5 ]

0 голосов
/ 09 марта 2009

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

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

Во-вторых, создайте оператор 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
0 голосов
/ 01 декабря 2008

Я бы использовал WHERE Subscriber_Email IN (Email, Email0) в качестве предложения WHERE

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 голосов
/ 29 ноября 2008

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

0 голосов
/ 29 ноября 2008

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

Я бы закодировал запрос

DELETE FROM Newsletter_Subscribers where (Subscriber_Email = Email or Subscriber_Email = EMail0)
0 голосов
/ 28 ноября 2008

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

"УДАЛИТЬ ИЗ Newsletter_Subscribeers WHERE ID IN (выберите идентификатор из [" & strDBPath & "Customers]. Клиенты, где Subscriber_Email = Email или Subscriber_Email = EmailO)"

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...