导航
  • 主页
  • 基础类
  • 应用实例
  • 新技术前沿

高分求解决方案:ASP+MSSQL(1千万条记录、数据库文件有3G)的查询检索超时问题

AMinfo 2007-12-10 11:47:00
我有数据库MSSQL01中有2个表如下:
表1:A02
字段:ID(自动编号)、AA、BB、CC、DD、EE、FF、GG
记录总数:300条记录左右
补充说明:字段ID为索引,AA、BB、CC、DD、EE、FF、GG里面的值非唯一性,有重复的
除了ID是自动编号类型外,其他字段全为整型

表2:DATAALL
字段:ID(自动编号)、AA、BB、CC、DD、EE、FF、GG、Prize
记录总数:1千万条记录
补充说明:字段ID为索引,AA、BB、CC、DD、EE、FF、GG里面的值非唯一性,有重复的
除了ID是自动编号类型外,其他字段全为整型

现在要实现的是:找出DATAALL表中AA、BB、CC、DD、EE、FF、GG这几个字段中的值要完全和A02表中的AA、BB、CC、DD、EE、FF、GG相同,如果找到相同的,则将DATAALL表中的Prize的值加1。

以下是我已经写好的ASP执行程序,可是运行时却出现超时提示,提示如下:

Microsoft VBScript 编译器错误 错误 '800a03f6'

缺少 'End'

/iisHelp/common/500-100.asp,行242

Active Server Pages 错误 'ASP 0113'

脚本超时

/prize.asp

超过了脚本运行的最长时间。您可以通过指定 Server.ScriptTimeOut 属性值来修改此限制或用 IIS 管理工具来修改它。

<%
response.buffer=true '启用缓冲处理
session.timeout=60 '是session的生存时间
Server.ScriptTimeout=60 '是服务器脚本超时时间
Const SqlDatabaseName = "MSSQL01"
Const SqlPassword = "sa"
Const SqlUsername = "sa"
Const SqlLocalName = "(local)"
ConnStr = "Provider = Sqloledb; User ID = " & SqlUsername & "; Password = " & SqlPassword & "; Initial Catalog = " & SqlDatabaseName & "; Data Source = " & SqlLocalName & ";"
Set conn = Server.CreateObject("ADODB.Connection")
conn.open ConnStr
If Err Then
err.Clear
Set Conn = Nothing
Response.Write "数据库连接出错,请检查连接字串。"'注释,需要把这几个字翻译成英文。
Response.End
End If
set rs=server.createobject("adodb.recordset")
sql="select * from A02 order by ID"
rs.open sql,conn,1,3
i=0
do while not rs.eof
set rs1=server.createobject("adodb.recordset")
sql="select * from DATAALL where AA="&rs("AA")&" and BB="&rs("BB")&" and CC="&rs("CC")&" and DD="&rs("DD")&" and EE="&rs("EE")&" and FF="&rs("FF")&" and GG="&rs("GG")
Response.write sql
rs1.open sql,conn,3,3
If not rs1.eof Then
rs1("Prize")=rs1("Prize")+1
rs1.update
End If
rs1.close
set rs1=nothing
Response.write i

i=i+1
rs.movenext
loop
rs.close
set rs=nothing
Conn.Close
set Conn = nothing
%>

以上是ASP代码,请高手帮帮忙,谢谢!
...全文
330 点赞 收藏 19
写回复
19 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
AMinfo 2007-12-11
非常感谢fcuandy,也谢谢各位的帮忙,通过fcuandy分批执行多次的方法,以1000000万条记录作为一次在查询分析器里面执行可以顺利通过,2000000万条则超时!

接下来将要碰到的问题是,进行比较的表不只有A02一个,还有A01、A03、A04、A05、A06...等表,而且最终还是需要通过ASP来实现类似此功能提供给客户端查询操作用。

此贴先结,再开新贴向大家请教ASP下如果高效进行SQL查询。谢谢大家!
回复
云中客 2007-12-11
建立索引时,也是有技巧的,并不是说列中值不唯一,就不能建索引

回复
云中客 2007-12-11
1。在程序代码中设置响应时间长些
2。对表查询进行优化,增加相关的索引,对语句进行优化
3。尽量利用存储过程或函数来代替在程序中操作数据库
4。对于更新数据量大的情况下,可以分批进行更新

回复
fcuandy 2007-12-11
直接在数据库服务器的查询分析器上运行那条语句看看结果如何.
建议在测试用的数据服务器上运行,以免造成不必要的损失.

如果造成查询分析器假死,或SQL当机,请尝试分段或者说分批执行update,即,用 where按聚集索引字段过滤,多次执行语句.
比如假设 dataAll有 id为int型,唯一值,聚集索引.那么根具id值的分布,可分多次执行
UPDATE a SET Prize=Prize+1
FROM DataALL a
INNER JOIN A02 b
ON a.aa=b.aa AND b.bb=a.bb AND b.cc=a.cc AND a.ee=b.ee AND a.ff=b.ff AND a.gg=b.gg
WHERE a.id>0 AND a.ID<=2000000 /*分批执行多次,每次更改这两个参数值,比如下一次为 >2000000 and a.id<=5000000*/


若能查询分析器没有死掉,那么可能原因是因为连接超时,请在asp代码里conn的实例创建后 即 set conn=server.create....之后加上以下两句
conn.CommandTimeout = 300 '//设置为5分钟,具体值是多少,你依具查询分析器执行那条语句时花费的时间来具体调整
conn.ConnectionTimeout = 300
回复
AMinfo 2007-12-11
已经分别对aa,bb,cc,dd,ee,ff,gg建立了索引,用了fcualdy提供的SQL CODE运行后1分钟左右提示:
[Microsoft][ODBC SQL Server Driver]超时已过期

回复
AMinfo 2007-12-10
对AA、BB、CC、DD、EE、FF、GG建立索引需要注意哪些选项呢?在建立索引时,要选择哪些选项?
回复
AMinfo 2007-12-10
AA、BB、CC、DD、EE、FF、GG无法建立索引
回复
dawugui 2007-12-10
AA、BB、CC、DD、EE、FF、GG这6个字段里面的值并非唯一性的啊,各字段里面的值都是重复的,这种情况如何索引?另外,已将Server.ScriptTimeout=6000设置成6000,结果还是一样出现“超时已过期”。
------------------------------
不建立唯一索引.
回复
xxsoft2007 2007-12-10
update a set a.Prize  = a.Prize  + b.cn
from DATAALL a inner join (select AA、BB、CC、DD、EE、FF、GG ,count(*) as cn
from A02
group by AA、BB、CC、DD、EE、FF、GG) b
on a.aa=b.aa and a.bb=b.bb and a.cc=b.dd and a.ee=b.ee and
and a.ff=b.ff and a.gg=b.gg
回复
AMinfo 2007-12-10
AA、BB、CC、DD、EE、FF、GG这6个字段里面的值并非唯一性的啊,各字段里面的值都是重复的,这种情况如何索引?另外,已将Server.ScriptTimeout=6000设置成6000,结果还是一样出现“超时已过期”。
回复
dawugui 2007-12-10
AA、BB、CC、DD、EE、FF、GG
有六个字段,对这六个字段分别建立索引.
回复
AMinfo 2007-12-10
已将ID做为主键索引
回复
dawugui 2007-12-10
把相关字段建立索引,主键.

除此无他法.
回复
fcuandy 2007-12-10
UPDATE a SET Prize=Prize+1
FROM DataALL a
INNER JOIN A02 b
ON a.aa=b.aa AND b.bb=a.bb AND b.cc=a.cc AND a.ee=b.ee AND a.ff=b.ff AND a.gg=b.gg


在两个表的aa,bb,cc,dd,ee,ff,gg上分别建索引.

试试吧,不一定好用,不太清楚你的重复率高不高.
回复
AMinfo 2007-12-10
直接在SQL里面用了xxsoft2007 的SQL代码:
UPDATE a
SET a.Prize =a.Prize+b.cn
FROM TCALL a INNER JOIN
(SELECT AA, BB, CC, DD, EE, FF, GG, COUNT(*) AS cn
FROM A02
GROUP BY AA, BB, CC, DD, EE, FF, GG) b ON a.AA = b.AA AND a.BB = b.BB AND
a.CC = b.CC AND a.DD = b.DD AND a.EE = b.EE AND a.FF = b.FF AND a.GG = b.GG

运行后提示以下错误信息:
[Microsoft][ODBC SQL Server Driver]超时已过期

还是超时问题。



回复
AMinfo 2007-12-10
用ASP代码来写的话如何优化?直接用SQL语句又该如何写呢?
回复
fcuandy 2007-12-10
sql="select * from A02 order by ID"
rs.open sql,conn,1,3
i=0
do while not rs.eof
set rs1=server.createobject("adodb.recordset")
sql="select * from DATAALL where AA="&rs("AA")&" and BB="&rs("BB")&" and CC="&rs("CC")&" and DD="&rs("DD")&" and EE="&rs("EE")&" and FF="&rs("FF")&" and GG="&rs("GG")
Response.write sql
rs1.open sql,conn,3,3
If not rs1.eof Then
rs1("Prize")=rs1("Prize")+1
rs1.update
End If
rs1.close
set rs1=nothing
Response.write i

i=i+1
rs.movenext
loop
rs.close
set rs=nothing
Conn.Close


这种代码,建索引也优化不了.
对一个记录集循环recordcount次,再动态生成recordcount次第二个记录集.
你对1000w记录的那个表进行了300次循环读,然后又进行了更新.

明明一条update语句可以搞定的,你写的这么复杂..
回复
中国风 2007-12-10
SqlCommmand 中的 CommandTimeout 属性
设置超时时间
回复
winjay84 2007-12-10
看你在这两张表使用AA,BB,CC,DD,EE,FF,GG这些字段的频率,使用组合索引,单个索引
回复
发动态
发帖子
MS-SQL Server
创建于2007-09-28

3.2w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
社区公告
暂无公告