提高运行3分钟以上的asp脚本性能

时间:2008-11-28 14:26:08

标签: sql asp-classic

我使用SQL语句删除另一个数据库中存在的记录,但这需要很长时间。

下面的代码还有其他替代方案可以更快吗?数据库是Access。

email_DB.mdb来自我要删除其他数据库中存在的电子邮件地址(表Newsletter_Subscribers) 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:DELETE FROM Newsletter_Subscribers WHERE CustID IN(从[“& strDBPath&”Customers]中选择CustID。订阅者,其中Subscriber_Email = Email或Subscriber_Email = EmailO)

我得到“参数太少。预计1.”执行行上的错误消息。

5 个答案:

答案 0 :(得分:0)

假设Customers表中存在ID列,SQL中的以下更改应该会提供更好的性能:

“DELETE FROM Newsletter_Subscribers WHERE ID IN(从[”& strDBPath&“Customers]中选择ID。订阅者,其中Subscriber_Email = Email或Subscriber_Email = EmailO)”

PS。理想的解决方案(从列名称判断)将是重新设计表格和首先插入电子邮件的代码逻辑。 DS

答案 1 :(得分:0)

尝试添加Access Querydef并调用它。

答案 2 :(得分:0)

听起来您在subscriber_enail字段上没有索引。这会强制进行表扫描(或几次)。在此字段上添加索引,您应该会看到显着的改进。

我会编码查询

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

答案 3 :(得分:0)

我会使用 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)"

我从经验中发现,在WHERE子句中使用OR谓词在性能方面可能是有害的,因为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)"

答案 4 :(得分:0)

我会尝试将其拆分为两个单独的数据库连接语句。

首先,获取第一个数据库中的电子邮件地址或ID列表(作为字符串)。

其次,构造一个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