首页 > 开发 > 综合 > 正文

OLE DB Method for SQL

2024-07-21 02:10:55
字体:
来源:转载
供稿:网友
在第一部分,我们讨论了如何优化 asp 代码。在这一部分,我们把重点放在数据访问上。

一般情况下,数据访问时间要比 asp 代码解释,编译时间长,不要让数据检索成为影响 asp 性能的瓶颈。

首先,讲一些老生常谈的话。比如:需要声明变量,要用 response.write sql_string 来进行调试,要用 on error resume
next 来捕获错误。不要在 application 和 session 中存储 connection 对象等等,都是一些很多人知道而又不屑一顾的常
识。

提高数据访问速度包含两方面内容:1 与数据库建立连接。2 检索数据。

建立高效的连接是优化数据库访问的第一步。你需要了解连接池的概念( 参见文章: 连接池(connection pooling)介绍 );了解
连接数据库的方法。另外,测试是很重要的,如果你想亲自进行测试,可以下载上一部分提到的 wast ,它可以模拟大量用户同时
点击的情况。在这里,假设你使用的数据库是 ms sql server 7.0 ,如果 操作系统是 nt ,那么你可以在性能监视器中监测
sql7 的用户连接数(counter:user connections);如果操作系统是98的话,可以使用 sql7 的 profiler。

下面,开始讨论如何与数据库建立连接,以及连接池的问题。

1. 使用 oledb

与数据库建立连接有三种方法:dsn,dsn-less,oledb( 参见文章: 用ado连接数据库的三种方法 )。建议使用 oledb。

2. 尽快释放数据库对象

假设有 page1.asp 和 page2.asp,在多人同时点击的情况下,服务器可能会这样工作:

第一个人:page1.asp 的1-5行,
第二个人:page1.asp 的1-5行,
第一个人:page1.asp 的6-20行,
第二个人:page1.asp 的1-5行,
第三个人:page1.asp 的1-5行,
第四个人:page1.asp 的1-5行,
第二个人:page1.asp 的6-20行,
第一个人:page2.asp 的1-5行,
......

设想一下:有几千人同时访问你的主页,那么,服务器就会执行数千行,数万行语句后才回到第一个人请求的页面上。因此,我们
应尽可能快的处理某个功能,某个任务。看下列代码:

<%
rs1.open strsql1,cnn1         'cnn1 is connection object
rs2.open strsql2,cnn2
rs3.open strsql3,cnn3
......
'处理 rs1
'处理 rs2
'处理 rs3
......
rs1.close
rs2.close
rs3.close
cnn1.close
cnn2.close
cnn3.close
%>

这种处理结果集的方法会占用比你想象要多的资源,正确的用法应为:

<%
rs1.open strsql1,cnn         'cnn is connection object
'处理 rs1
rs1.close
cnn1.close
......
rs2.open strsql2,cnn
'处理 rs2
rs2.close
cnn2.close
......
rs3.open strsql3,cnn
'处理 rs3
rs3.close
cnn3.close

......
%>

或许你会说:在 rs2 的处理中,我还需要 rs1 的值,所以不能在处理 rs2 前关闭 rs1。那么解决这个问题更好的办法是采用
getrows 和 getstring,在后面会有详细的说明。

尽快的释放对象是保证数据库连接重用的前提。( 参见文章: 让数据库的连接更有效 )

3. 创建 connection 对象,充分利用连接池。

看下列代码:

'创建 connection object,打开 recordset
set cnn = server.createobject("adodb.connection")
cnn.open strconnection
set rs = server.createobject("adodb.recordset")
rs.open strsql,cnn

'直接打开 recordset
set rs = server.createobject("adodb.recordset")
rs.open strsql,strconnection

在 asptoday 的 enhancing performance in asp - part 2 中对这两种方法进行了测试,结果表明直接打开 recordset 比创
建 connection 快23%(快在页面处理上,检索数据库的速度是一样的。)所以,这篇文章的结论是:when working with a
single recordset,pass the connection string into the activeconenction property.

我对此有异议:快的代码不一定是好的代码。

首先要说明的是,直接打开 recordset 的方法依然要创建与数据库的连接,只不过是由 ado 自动完成的。其次,这个
connection 只有在该页面处理完后才能被释放(不管是 recordset.close 还是 set recordset = nothing 都不能做到释放该
对象)。

dim rs
dim strcnn
strcnn = "driver={sql server};server=.;database=pubs;uid=sa;pwd=;ole db services=-1;"
for i = 1 to 20
    set rs = server.createobject("adodb.recordset")
    rs.open "select * from authors",strcnn
    rs.close
    set rs = nothing
next    


运行上面的代码,在性能监视器中你会发现数据库的连接被创建了20个!

dim cnn,rs
strcnn = "driver={sql server};server=.;database=pubs;" &_
    "uid=sa;pwd=;ole db services=-1;"
for i = 1 to 20
    set cnn = server.createobject("adodb.connection")
    cnn.open strcnn
    set rs = server.createobject("adodb.recordset")
    rs.open "select * from authors",cnn
    rs.close
    set rs = nothing
    cnn.close
    set cnn = nothing
next

采用上面的代码,连接数只需要2个!(只为说明问题,不考虑速度)

还有一点要说明的是:服务器处理 asp 时不是一次只处理一个,也不是一次就把整个页面处理完,没有关闭的连接只会占用更多
的资源。所以,尽快的释放 connection ,使它回到连接池中才是良好的编程习惯。连接池是服务器共享的资源,它不属于某个
asp,也不属于某个 session,或者某个 application。

wast 是我常用的测试工具,但是测试是一种手段,代替不了实际。如果你对 wast 的工作方式感兴趣,可以到它的主页去看看。
http://webtool.rte.microsoft.com/

4. 为多个 recordset创建一个 connection 对象

dim cnn,rs1,rs2,r3
strcnn = "driver={sql server};server=.;database=pubs;uid=sa;pwd=;ole db services=-1;"
set cnn = server.createobject("adodb.connection")
cnn.open strcnn
set rs1 = server.createobject("adodb.recordset")
rs1.open "select * from authors1",cnn
set rs2 = server.createobject("adodb.recordset")
rs2.open "select * from authors2",cnn
set rs3 = server.createobject("adodb.recordset")
rs3.open "select * from authors3",cnn
.....

道理很简单,这种做法不需要为每一个 recordset 创建一个连接,只要传递一个引用就够了。

5. 与多个数据库连接的问题。

在大部份应用中,我们只对一个数据库进行操作,但有时也会碰到与多个数据库连接的情况。下面我们讨论两种连接方式:

'第一种:两个 connection,两个 recordset。
set cnn1 = server.createobject("adodb.connection")
set cnn2 = server.createobject("adodb.connection")
cnn1.open "provider=sqloledb;data source=210.75.56.37;initial catalog=pubs;user
id=coolbel;password=coolbel.com;"
cnn2.open "provider=sqloledb;data source=210.75.56.37;initial catalog=coolbel;user
id=coolbel;password=coolbel.com;"
set rs1 = server.createobject("adodb.recordset")
set rs2 = server.createobject("adodb.recordset")
rs1.open "select * from authors",cnn1
rs2.open "select * from mytable",cnn2
......

'第二种:一个 connection,两个 recordset。
set cnn = server.createobject("adodb.connection")
cnn.open "provider=sqloledb;data source=210.75.56.37;user id=coolbel;password=coolbel.com;"
set rs1 = server.createobject("adodb.recordset")
set rs2 = server.createobject("adodb.recordset")
rs1.open "select * from pubs..authors",cnn
rs2.open "select * from coolbel..mytable",cnn
......


第二种方法极不可取,不仅速度低,而且浪费资源。其效率低下的根本原因在于这种连接方式没有利用连接池,使得每一次请求都
要重新创建与数据库的连接。

click!测试第一种代码    click!测试第二种代码    ( coolbel 不稳定,需要多测试几遍。)

6. 对于 disconnected recordset,不要忘记使 activeconnection = nothing
中国最大的web开发资源网站及技术社区,
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表