【问题标题】:Reduced performance when creating object in classic asp在经典 asp 中创建对象时性能降低
【发布时间】:2023-03-10 07:19:01
【问题描述】:

为了测量网站性能,我创建了一个简单的日志记录 sub,以查看在执行经典 asp 页面期间哪些部分较慢。

sub log(logText)
    dim fs, f
    set fs = Server.CreateObject("Scripting.FileSystemObject")
    set f = fs.OpenTextFile("log.txt", 8, true)
    f.WriteLine(now() & " - " & logText)
    f.Close
    set f = Nothing
    set fs = Nothing
end sub

log "Loading client countries"
set myR = Server.CreateObject("ADODB.RecordSet")
myR.ActiveConnection = aConnection
myR.CursorLocation=2
myR.CursorType=3
myR.LockType=2
myR.Source = "SELECT * FROM CC ORDER BY ccName ASC"
log "Opening db connection"
myR.open()
log "Opened db connection"

以下是结果(仅显示时间部分):

...
11:13:01 - Loading client countries
11:13:06 - Opening db connection
11:13:06 - Opened db connection
...

创建ADODBRecordSet 并设置一些属性大约需要 5 秒。这并不总是发生,有时代码执行得很快,但通常在我重新加载页面时 几分钟后,加载时间或多或少与示例相同。这真的是服务器/资源问题还是我应该考虑重写代码? (我最好的选择是写在C# 中,但无论如何我必须先研究这段代码才能继续前进)。

更新:我在收到第一条评论后添加了更多代码,以提供更多代码。说明:代码创建了一个带有检索到的国家/地区的combobox(选择菜单)(它从上一段代码停止的地方继续)。

if not myR.eof then
    clientCountries = myR.getrows
    send("<option value='0'>Select country</option>")
    log "Creating combobox options"
    for i = 0 to ubound(clientCountries, 2)
        if cstr(session("clientCountry")) <> "" then
            if cstr(clientCountries(1, i)) = cstr(session("clientCountry")) then
                isSelected = "selected" else isSelected = ""
            end if
        end if
        if cstr(session("clientCountry")) = "" then
            if cstr(clientCountries(1, i)) = "23" then
                isSelected = "selected"
            else
                isSelected = ""
            end if
        end if
        optionString = ""
        optionString = clientCountries(2, i)
        send("<option value='" & clientCountries(1, i) & "' " & isSelected & ">" & convertToProperCase(optionString) & "</option>")
    next
    log "Created combobox options"
end if
myR.Close
myR.ActiveConnection.close
myR.ActiveConnection = nothing
set myR = nothing
log "Loaded client countries"

接下来的两个日志条目如下:

11:13:06 - Creating combobox options
11:13:06 - Created combobox options
...

到目前为止,SELECT 查询作为页面的其余部分(2 或 3 个查询更多)或多或少在下一秒内执行。唯一减慢页面速度的部分是您在日志的第一部分中可以看到的内容。我不确定是否可以分析 SQLServer,因为我只有 cPanel 访问权限。这是我知道的唯一方法,除非我可以看看其他东西。

【问题讨论】:

  • 您是否尝试过分析 SQL 服务器?我想看看你的选择真的花了多长时间。
  • @NathanRice 我已经用更多信息更新了这个问题,感谢您的关注。
  • 需要多长时间(作为猜测)?这样的事情不应该超过几毫秒。
  • 一个小的改进:在 FOR 循环中应该只有一个 IF 语句。交换它们并使用 ELSE 而不是第二个 IF。
  • @BlueSix 不幸的是,从我目前的研究来看,经典的 asp 无法通过毫秒。

标签: performance optimization asp-classic


【解决方案1】:

首先,检查您的连接字符串,我在某些提供商处遇到过较慢的时间。我为经典 asp 找到的最佳提供商是 sqloledb

其次,在对 GetRows() 数组执行 For 语句之前,我将关闭我的 SQL 对象。如果不需要,你不想让它保持打开状态。

第三,我会使用存储过程。通过节省编译时间,您将获得性能提升。

第四,我会不惜一切代价避免使用SELECT * 语句,而是只返回我需要的列。 (您的代码看起来只需要 2 列)

第五,我会在表上建立索引花费比预期更长的时间。

如果这不能解决问题,我会考虑其他语言/解决方案。不确定数据集是什么样的,所以不能说是否应该考虑使用平面文件数据库。

另外,试试这个记录集,看看会发生什么:

Set myR = Server.CreateObject("Adodb.Recordset")
myR.Open "SELECT * FROM CC ORDER BY ccName ASC", aConnection
If myR.RecordCount > 0 Then clientCountries = myR.GetRows()
myR.Close
Set myR = Nothing

If IsArray(myR) Then
  For ....

【讨论】:

  • connectionString 如下所示:Provider=SQLNCLI11;Server=LOCALHOST\SQLEXPRESS;Database=*****;Uid=*****; Pwd=******;
  • 我刚刚辞掉了这份工作,因为我无法与经理们讲道理并向他们展示技术上的困难,但我仍然可以访问并且可以说服他们让我解决这个问题。但是,我想指出的是,我主要关心的是打开数据库之前花费的时间,所以我想连接提供程序是有道理的。我不知道我是否可以使用其他提供商,所以我必须检查它是否可用或应该安装。无论如何,这毕竟会解决,一定会尝试你的建议,谢谢!
  • 是的,你应该试试这个提供商,对我来说还不错:Provider=sqloledb; Data Source=(local); Initial Catalog=MyDB; User Id=***; Password=***;
  • 新入职的程序员尝试了你的方案,可惜速度问题没有解决,所以这看起来更像是服务器资源问题。
猜你喜欢
  • 1970-01-01
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-12
  • 1970-01-01
相关资源
最近更新 更多