- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) > web開(kāi)發(fā) > ASP >
- set rs=conn.execute,set rs=server.createobject(“ADODB.recor
經(jīng)常用asp的同行,可能會(huì )建議用set rs=conn.execute(sql)來(lái)代替set rs=server.createobject(“ADODB.recordset”):rs.open conn,sql,1,1。還有一些同行更提出了用set rs=conn.execute(sql):res=rs.getRows(100)來(lái)優(yōu)化ASP程序。其實(shí)在沒(méi)有做此實(shí)驗前,我也是很相信這種方法的。實(shí)際效果果真如此嗎?經(jīng)過(guò)一番測試,我發(fā)現結果遠非如此,set rs=server.createobject(“ADODB.recordset”)的方法比set rs=conn.execute的方法快4~5倍。這個(gè)結果您信嗎?不信,更我來(lái)一起做這個(gè)測試。
數據說(shuō)明真相。首先創(chuàng )建一個(gè)多記錄的數據庫。
set conn=createobject("adodb.connection") conn.open "provider=microsoft.jet.oledb.4.0;data source=E:\labs\miaoqiyuan.cn\g.mdb" do while conn.execute("select count(id) from site")(0)<1000000 conn.execute("insert into site(sitename,siteadmin,siteurl,sitekey) values('苗啟源','http://localhost/app_login/','http://www.miaoqiyuan.cn','e10adc3949ba59abbe56e057f20f883e')") loop
經(jīng)過(guò)幾個(gè)小時(shí)的運行,我得到了一個(gè)有63萬(wàn)多條記錄的數據庫。數據庫大小為99.7MB(測試數據庫下載地址)。
為了保證數據的真實(shí)性,我們用公共的頭部header.asp來(lái)保存數據庫連接字符串。footer.asp來(lái)保存運行時(shí)間。
運行環(huán)境,Windows 2003 Server SP2。IIS6.0,CPU E2200 2.2GHz,內存2Gx2。硬盤(pán)300G SATA+80G ATA。
公共頭部:header.asp
<% startTme=timer() set conn=server.createobject("ADODB.connection") conn.open "provider=microsoft.jet.oledb.4.0;data source="&server.mappath("g.mdb") %>
公共底部:footer.asp
<hr />總共用時(shí):< %=(timer()-startTme)*1000%>毫秒
測試方法:以三種方式,每頁(yè)100條記錄。同時(shí)讀取第6000頁(yè)到6099頁(yè)的記錄共一萬(wàn)條,并測出運行時(shí)間。
test1.asp,采用set rs=server.createobject(“ADODB.recordset”)的方法。
< % for k=0 to 100 response.write "<br /><br />第"&(6000+k)&"頁(yè)<hr />" set rs=server.createobject("adodb.recordset") rs.open "select * from site",conn,1,1 rs.pagesize=100 rs.absolutepage=6000+k i=0 do while not rs.eof and i<100 i=i+1 response.write rs("id")&":"&rs("sitename")&"<br />"&vbCrlf rs.movenext loop rs.close set rs=nothing next %>
test2.asp 采用set rs=conn.execute()的方法
< % for k=0 to 100 response.write "<br /><br />第"&(6000+k)&"頁(yè)<hr />" set rs=conn.execute("select * from site") rs.movefirst rs.move (6000+k)*100 i=0 do while not rs.eof and i<100 i=i+1 response.write rs("id")&":"&rs("sitename")&"<br />"&vbCrlf rs.movenext loop rs.close set rs=nothing next %>
至于getRows,這種方法只能算是返回結果的優(yōu)化,并不能算是一種方法。我們采用兩種返回結果的方式測試。test3.asp采用set rs=server.createobject(“ADODB.recordset”)的方法,test4.asp采用set rs=conn.execute(sql)的方法
< % for k=0 to 100 response.write "<br /><br />第"&(6000+k)&"頁(yè)<hr />" set rs=server.createobject("adodb.recordset") rs.open "select * from site",conn,1,1 rs.pagesize=100 rs.absolutepage=6000+k res=rs.getRows(100) rs.close set rs=nothing for i=0 to 99 response.write res(0,i)&":"&res(1,i)&"<br />"&vbCrlf next next %>
< % for k=0 to 100 response.write "<br /><br />第"&(6000+k)&"頁(yè)<hr />" set rs=conn.execute("select * from site") rs.movefirst rs.move (6000+k)*100 res=rs.getRows(100) rs.close set rs=nothing for i=0 to 99 response.write res(0,i)&":"&res(1,i)&"<br />"&vbCrlf next next %>
下面是我的測試結果:
為什么會(huì )出現這種結果呢?set rs=conn.execute(sql),set rs=server.createobject(“ADODB.recordset”)為什么為相差這么多?對比一下test1.asp、test3.asp與test2.asp、test4.asp,除了返回結果的方式不同,還有一處就是rs.move。難道是這個(gè)原因?把test3.asp的代碼稍微修改一下。存為test5.asp。
< % for k=0 to 100 response.write "<br /><br />第"&(6000+k)&"頁(yè)<hr />" set rs=server.createobject("adodb.recordset") rs.open "select * from site",conn,1,1 rs.movefirst rs.move (6000+k)*100 res=rs.getRows(100) rs.close set rs=nothing for i=0 to 99 response.write res(0,i)&":"&res(1,i)&"<br />"&vbCrlf next next %>
經(jīng)過(guò)測試,test5.asp能比test3.asp快0.1~0.2秒,如果讀取100條數據,這點(diǎn)差距可以忽略不計。
由此可見(jiàn):set rs=conn.execute的方式確實(shí)比set rs=server.createobject(“ADODB.recordset”)方式慢,在學(xué)校的時(shí)候,老師教的一般都是set rs=server.createobject(“ADODB.recordset”)的方法,真正工作室,學(xué)習所謂的高手set rs=conn.execute優(yōu)化的方法,結果最終發(fā)現,而鄙視用老師教的方法寫(xiě)程序的同行,最終發(fā)現還是老師教的速度快,而且set rs=server.createobject(“ADODB.recordset”)的方法比set rs=conn.execute的方法快4~5倍。囧。。。。
難道set rs=conn.execute就一無(wú)是處了嗎?在數據插入方面,兩者的差別有多大呢?
下面是其他網(wǎng)友的補充
沒(méi)有可比性,為什么非要比呢?
set rs=conn.execute()
rs.getrows()
這種方法一般用在數據量少的情況下,比如說(shuō)只有幾十幾百條數據的情況下,它只讀一次數據庫,然后把結果存入一個(gè)二維數組中,在這之后的操作就不需要數據庫,而是直接對內存中的數據進(jìn)行操作了,速度絕對比用常規方法快,而且也節省資源。而用常規方法的話(huà),數據庫操作得多少次?而在日常的情況下,一次讀取大量數據的情況是很少的,所以在很多地方都提到使用上面這種方法,就是緣于此。
還有上面比的分頁(yè),常規方法由于它自身的局限,對數據庫的操作很費資源的,別說(shuō)只是快那零點(diǎn)幾秒,好的程序到最后拼的就是那零點(diǎn)幾秒。
什么時(shí)候用什么?
那就憑個(gè)人經(jīng)驗積累的感覺(jué)了:
如果只需要一筆帶過(guò)的碰碰數據庫,用execute
如果要對數據庫作比較龐雜的操作!則最好用 rs.open
rs.open sql,conn:如果sql是delete,update,insert則會(huì )返回一個(gè)關(guān)閉的記錄集,在使用過(guò)程中不要來(lái)個(gè)rs.close在文件最后再寫(xiě)rs.close中間可以來(lái)多個(gè)記錄集rs1.open sql1,conn,最后一塊關(guān)閉記錄集:rs.close rs1.close
conn.execute(sql):如果sql是update,insert,delete則應該使用conn.execute(sql)也可以不要括號conn.execute sql
如果sql是select語(yǔ)句則應該使用set rs=conn.execute(sql)括號一定要,不能省略:這是因為vb的特性,帶返回值的調用必須加括號,不帶返回值的調用可以不要括號。
1.conn.execute
sql="select * from admin where username='xiaozhu'"
set rs=conn.execute(sql)
'執行完以后自動(dòng)關(guān)閉記錄集
'最后只需要關(guān)閉連接就可以了
conn.close
set conn=nothing
2.rs.open
set rs=server.createobject("adodb.recordset")
sql="select * from admin where username='xiaozhu'"
rs.open sql,conn,1,1
'可以自己設定一些參數,即鎖定和游標的移動(dòng)方式
'最后要關(guān)閉記錄集和連接
rs.close
set rs=nothing
conn.close
set conn=nothing
3.command.execute
sql="select * from admin where username='xiaozhu'"
set rs=command.execute(sql)
1.
set rs=conn.execute("如果是select語(yǔ)句") 得到的rs.recordcount=-1
rs.open sql,conn("sql為select語(yǔ)句") 得到的rs.recordcount為正常的記錄數
2.
rs.open是打開(kāi)數據庫 conn.execute 是執行SQL指令
set rs=conn.execute(insert,update,delete)返回一個(gè)關(guān)閉了的記錄集
set rs=conn.execute(select)返回一個(gè)沒(méi)有關(guān)閉的記錄集
3.
CONN.EXECUTE(SQL,RowsAffected,C)
參數含義:
SQL的值可以是SQL語(yǔ)句、表名、存儲過(guò)程名,也可以是數據提供者所能接受的任意字符串。為了提高性能,最好為C參數指定合適的值
可選參數RowsAffected將返回INSERT、UPDATE或DELETE查詢(xún)執行以后所影響的數目。這些查詢(xún)會(huì )返回一個(gè)關(guān)閉的Recordset對象。
一個(gè)SELECT查詢(xún)將返回RowsAffected值為-1并且返回帶有一行或多行內容的打開(kāi)的Recordset。
4.
conn.execute sql適合于不需返回recordset對象時(shí)使用,比如下面的代碼:
sql="delete from enews where id="&cstr(id)
conn.execute sql
如果需要返回recordset對象,則使用如下代碼:
sql="select from enews where id="&cstr(id)
set rs = conn.execute(sql)
如果去掉execute(sql)這兒的括號(即為set rs = conn.execute sql),就會(huì )提示“語(yǔ)句未結束”這樣的錯誤提示,我翻看了一下語(yǔ)法格式,發(fā)現有二種格式,詳解如下:
格式一:Connection對象名.Execute(SQL指令).
格式二:Connection對象名.Execute(數據表名)。
附:
set rs = conn.execute(sql)
是帶有返回值的,一般sql為查詢(xún)的時(shí)候使用。如
set rs = conn.execute("select * from ...")
當然執行insert into 和delete也是可以的
set rs = conn.execute("insert into table (f1,f2..")
但是要創(chuàng )建Recordset對象,占用服務(wù)器資源。在insert into, delete的時(shí)候我們一般不需要返回記錄集。所以我是這樣認為的:
在使用查詢(xún)的時(shí)候,用 set rs = conn.execute("select * from table")
在插入和刪除時(shí)候,用 conn.execute("delete from table where ...")
第二種方式代碼簡(jiǎn)潔,不需要顯式地創(chuàng )建Recordset對象(但實(shí)際上好象是隱式創(chuàng )建的)
第二種方法還有一些簡(jiǎn)潔的寫(xiě)法:如,最某表的記錄數
dim count
count = conn.execute(select count(*) from table)(0)
上面的語(yǔ)句等于
count = conn.execute(select count(*) from table).fields(0).value
綜上:區別在于set rs = conn.execute是顯示創(chuàng )建recordset對象,而conn.execute是隱式的。
能用conn.execute的時(shí)候就用conn.execute,好處有
一、代碼簡(jiǎn)潔
二、效率應該有所提高
再摘引一下:(srnld(天涯))
形成記錄集的方法有三種 CONN.execute rs.open Command.execute
方法用法大大不通
通常 Set rs=CONN.execute(SQL)
或直接 rs=CONN.execute(SQL)
和 Set rs=Server.CreateObject("ADODB.Recordset")
rs.open SQL,CONN,0,1 或 rs.open SQL,CONN
這種情況 通常open比上一個(gè)性能要好那么一丁點(diǎn)
( command對象更靈活,執行范圍更廣)
使用 CONN.execute 可以不用關(guān)閉直接執行下一個(gè) set rs=conn.execute(SQL)
但性能速度會(huì )大打折扣!!
大約要慢 2~5倍!!(這是我在msSQL循環(huán)1000次親自測試過(guò)的,不信你馬上自己測試),所以執行下一個(gè) rs=conn.execute之前!!一定要關(guān)閉掉!是個(gè)好習慣!
使用單一對象的rs rs.open在open下一個(gè)記錄集之前,必需要求顯示關(guān)閉,否則出錯,速度在SQL,CONN,0,1的情況下可前者基本一樣
所以我喜歡使用直設置一個(gè) CreateObject("adodb.recordser")(在不需要多個(gè)記錄集交錯操作的情況下,多個(gè)也不礙是!)
然后從頭用到尾!!!
開(kāi)門(mén)關(guān)門(mén)開(kāi)門(mén)關(guān)門(mén)~~~~~咵踏咵踏~~~~
最后一個(gè) set rs=nothing 化上句號,爽!
更主要是 open提供非常靈活的操作數據庫元數據的非常多的屬性!!
打開(kāi)百寶箱,金光燦燦什么都看見(jiàn)!
有很多情況下是非得用open來(lái)做的!
而conn.execute 想黑布下?lián)Q膠卷~~~偷偷摸摸~~非常單一!!!
比如:
rs1.open SQL1,conn,0,1
rs.open SQL,conn,1,3
if rs(0)<0 then rs(0)=0
rs(1)=aaa
rs(2)=bbb
rs.update ' 更新記錄集寫(xiě)到數據庫
rs.addnew '加一條新記錄
rs(0)=1
rs(1)=ddd
rs(2)=kkk
rs.update
id=rs(3) rs(s) '取的字段是自動(dòng)編號 立即獲得新記錄的自動(dòng)編號id //這是非常常用的
rs1.addnew 對rs1添加關(guān)連使用id rs的新記錄
rs1("id")=id
rs1(1)=...
..
rs1.update
rs1.close:set rs1=nothing
rs.close:set rs=nothing
上面的操作如果采用CONN.execute 則要用到四個(gè) CONN.execute
CONN.execute("update ..")
CONN.execute("insert into 表1:")
rs=CONN.execute("select 新的自動(dòng) id")
CONN.execute("insert into 表二")
那一種方法邏輯條理更好~~一目了然
======================
還有一個(gè)有趣的使用Recordset open記錄的方法!!
我想起來(lái)是有點(diǎn)費解
Set rs=server.CreateObject("Adodb.recordset")
Set rs=server.CreateObject("Adodb.recordset")
rs.open SQL1,CONN
rs.open SQL2,CONN
'嘿嘿~~~這是同時(shí)設置同名的兩個(gè)對象來(lái)打開(kāi)兩個(gè)記錄集,而且是可用的!
'只要取的列名合乎這兩個(gè)記錄集中元數據
'則正常操作!!
擴展開(kāi)來(lái)
Set rs=server.CreateObject("Adodb.recordset")
Set rs=server.CreateObject("Adodb.recordset")
Set rs=server.CreateObject("Adodb.recordset")
Set rs=server.CreateObject("Adodb.recordset")
rs.open SQL1,CONN
rs.open SQL2,CONN
rs.open SQL3,CONN
rs.open SQL4,CONN
這樣大于二個(gè)同名的 rs我還沒(méi)試過(guò)!!
感覺(jué)有點(diǎn)相當與 SQL聯(lián)合查詢(xún)再打開(kāi)記錄集~~~
以前我這樣用過(guò)!!應該不是眼花!!
到此這篇關(guān)于set rs=conn.execute,set rs=server.createobject(“ADODB.recordset”)的性能對比的文章就介紹到這了,更多相關(guān)conn.execute與ADODB.recordset的對比內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站