简体   繁体   English

改善耗时3分钟以上的ASP脚本性能

[英]Improve asp script performance that takes 3+ minutes to run

I use an SQL statement to remove records that exist on another database but this takes a very long time. 我使用SQL语句删除另一个数据库上存在的记录,但这需要很长时间。

Is there any other alternative to the code below that can be faster? 除了下面的代码,还有其他替代方法可以更快吗? Database is Access. 数据库是访问。

email_DB.mdb is from where I want to remove the email addresses that exist on the other database (table Newsletter_Subscribers) customers.mdb is the other database (table Customers) email_DB.mdb是我要删除另一个数据库(表Newsletter_Subscribers)上存在的电子邮件地址的客户。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

EDIT: Tried the SQL below from one of the answers but I keep getting an error when running it: 编辑:从下面的答案之一尝试了下面的SQL,但运行它时我不断收到错误:

SQL: DELETE FROM Newsletter_Subscribers WHERE CustID IN (select CustID from [" & strDBPath & "Customers].Customers where Subscriber_Email = Email or Subscriber_Email = EmailO) SQL:在Newsletter_Subscribers中删除CUSTID IN(从[“&strDBPath&” Customers]中选择CustID。Customer_Email= Email或Subscriber_Email = EmailO的客户)

I get a "Too few parameters. Expected 1." 我得到“参数太少。预期为1”。 error message on the Execute line. 执行行上的错误消息。

Assuming there's an ID-column present in the Customers table, the following change in SQL should give better performance: 假设“客户”表中存在一个ID列,则SQL中的以下更改应提供更好的性能:

"DELETE FROM Newsletter_Subscribers WHERE ID IN (select ID from [" & strDBPath & "Customers].Customers where Subscriber_Email = Email or Subscriber_Email = EmailO)" “从Newsletter_Subscribers的ID IN中删除(从[“&strDBPath&” Customers]中选择ID。其中Subscriber_Email =电子邮件或Subscriber_Email = EmailO的客户)”

PS. PS。 The ideal solution (judging from the column names) would be to redesign the tables and code logic of inserting emails in the first place. 理想的解决方案(从列名来看)将是重新设计表格和首先插入电子邮件的代码逻辑。 DS DS

尝试添加一个Access Querydef并调用它。

It sounds like you do not have an index on the subscriber_enail field. 听起来您在subscriber_enail字段上没有索引。 This forces a table scan ( or several). 这将强制进行表扫描(或多次)。 Add an index on this field and you should see significant improvement. 在此字段上添加索引,您应该会看到明显的改进。

I would have coded the query 我会编码查询

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

I would use WHERE Subscriber_Email IN (Email, Email0) as the WHERE clause 我将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)"

I have found from experience that using an OR predicate in a WHERE clause can be detrimental in terms of performance because SQL will have to evaluate each clause separately, and it might decide to ignore indexes and use a table scan. 我从经验中发现,在WHERE子句中使用OR谓词在性能上可能是有害的,因为SQL将不得不分别评估每个子句,并且它可能决定忽略索引并使用表扫描。 Sometime it can be better to split it into two separate statements. 有时最好将其拆分为两个单独的语句。 (I have to admit I am thinking in terms of SQL Server here, but the same may apply to Access) (我必须承认我在这里就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)"

I would try splitting this into two separate statements with separate database connections. 我会尝试将其拆分为两个具有独立数据库连接的独立语句。

First, fetch the list of email addresses or IDs in the first database (as a string). 首先,在第一个数据库中获取电子邮件地址或ID的列表(作为字符串)。

Second, construct a WHERE NOT IN statement and run it on the second database. 其次,构造一个WHERE NOT IN语句并在第二个数据库上运行它。

I would imagine this would be much faster as it does not have to interoperate between the two databases. 我想这会更快,因为它不必在两个数据库之间进行互操作。 The only possible issue would be if there are thousands of records in the first database and you hit the maximum length of a sql query string (whatever that is). 唯一可能的问题是,如果第一个数据库中有成千上万条记录,而您达到了sql查询字符串的最大长度(无论是什么)。

Here are some useful functions for this: 这是一些有用的功能:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM