建站常识

asp+sql 程序优化常见技巧

发布时间 | 2017/8/18  点击 | 

1. 数据库结构优化

a. 比如一些标志信息是否认证之类的字段要建索引却没有建

b. 表没有设主键,加上主键

c. 外键一般都要加上索引

2. 程序优化

a. 当只限取前面N条记录时,不要用 select * ,然后再用ADO分页改为 select top N 字段列表,这样的语句会高效很多

b. 统计记录数时不要用 select * from .... 这样的语句,改用 select count(1) from .... 这样会好很多

c. 尽量避免使用 select * from table 这样的sql语句,这样会导致程序从数据库里读取太多无用的数据,一般来说应该使用select 字段1,字段2 from table 这种形式,只从数据库里读取必要的数据,这样能大大提高程序读取数据库的效率

d. 不要用嵌套查询,比如

<% sql = "select col1,col2 from a"

set rs = server.createobject("adodb.recordset")

rs.open sql,conn,1,1

while not rs.eof

sql2 = "select col1,col2 from b where id=" & rs("id")

set rs2 = server.createobject("adodb.recordset")

rs2.open sql2,conn,1,1 '这里用了嵌套查询,效率会下降很多,如果数据库的时候根本没法运行

while not rs2.eof

response.write rs("id") & "=" & rs2("name")

rs2.movenext

wend

rs.movenext

wend%>

如果改为

<% sql = "select a.id ,b.name from a left join b on b.id=a.id" '使用连表操作,并用具体的字段名代替 *,程序是高效很多

set rs = server.createobject("adodb.recordset")

rs.open sql,conn,1,1        

while not rs.eof

response.write rs("id") & "=" & rs("name")

rs.movenext

wend %>

3. 如果网站的访问量大并且数据库查询操作的任务比较重,要考虑采用自动生成静态页面然后定时自动更新的技术

4. 对于 access 数据库:

access 数据是一个桌面型的数据库系统,它只能应付一些数据量少且访问量不大的网站,如果access的数据库超过100M 以上,性能会急速下降,并且 access 数据库的数据库驱动程序只能应付同时15个进程共享,也就是说它最多只能允许15个人同时打开它,对于大访问量的网站来说这是很低的一个数值,所以一般访问量大或者是数据量大的网站一般要采用 sqlserver 或者 mysql 等高性能的数据库服务器平台。

有很多人使用 access 数据库时并没有对数据库的结构进行优化,这也是造成网站程序效率低下的另一个重要原因。

一般来说每个数据表都要设置一个主键,并且其外键一般都要建立索引,还有一些标志性的字段(如果标记一条信息是否是通过审核等)如果不是布尔型的话,一般来说也应该建立索引。

在查询程序优化方面 , 如果用 ADODB.Recoedset 自带的分页功能,也是存在问题,因为用ADO分页的话,这个对象是先将很多的记录选出来,加载到对象里(这将导致这个对象可能会加载成千上万的记录),再在对象里通过移动记录游标等操作来达到定位到某一行的目的,当数据量大的时候,性能也会急速下降。

如果采用 where RecID NOT IN(....) 这种结构的话,虽然记录集不会加载很多的数据,但是在数据库引擎在查询时做 这种NOT IN(...) 的比较是很费时间的,比如 NOT IN 的列表里有 1000 个记录ID,这在查询是将导致对整个数据表的每一条记录都跟这1000个ID进行比较,比如数据表里有 3000 条记录,那么执行这条 sql 的时候将导致 3000*1000 这么多次的比较,效率之低是可想而知的.   对于分页的优化方法:采用分步查询,这个方法可能要对数据表的结构作一些修改。

1. 数据表本身的主键( 比如是 RecID )应该是数字类型的。

2. 要查询分页的时候

(1). 先得出不应该包含在最终查询结果里的记录的最大ID号,比如要查询第 100 条记录以后的 N (N=每页的记录数) 条记录,可这样做:

<% SQLMAXID = "SELECT MAX(RecID) FROM(SELECT TOP 100 RecID FROM ChatRec WHERE RecID>0 ORDER BY RecID)" '这里只返回一个值,就是最大的%>

(2). 执行最终的数据查询 比如<%  SQL = "SELECT TOP 每页的记录条数 * FROM ChatRec WHERE RecID>("& SQLMAXID &") ORDER BY RecID"  '这里是找出 ID > MAXID 的前 N 条记录%>

这样的话避免用 NOT IN(...) 这个语句,效率会提高很多

说明:用这个方法有一点一定要注意的是子查询跟主查询都必须要按某个字段用相同的规则排序,比如像例子中的 ORDER BY RecID

并且一般建议用主键来进行排序5.asp程序中应尽量避免用 on error resume next

很多用户会采用 on error resume next 来屏蔽掉出错信息,这样虽然可以让访客看不到出错信息,界面友好一些,但是这样可能会带来非常严重的问题:当程序出错后,如果没有及时的捕获异常,从而中止程序执行的话,很空间导致程序出现死循环,导致服务器当机,所以只有在非常必要的情况下才好使用 on error resume next ,并且在使用on error resume next后及时捕获异常,如果出现错误就中止程序执行。 比如:

<%  set conn = Server.CreateObject("ADODB.Connection")connstr = "Driver={SQL Server};Server=db107.72dns.com;UID=abc;WD=abc;Database=abc"on error resume next

'这里的用 on error resume next 是为了屏蔽连接数据库时出错的信息

err.clearconn.open connstrif err.number<>0 then  '这里开始及时捕获异常,中止程序执行,否则很容易死循环而令服务器当机

response.write "链接数据库服务器出错"

response.endend if %>

相关信息