The*_*ver 5 object recordset asp-classic
我想知道,以下哪个示例最适合在我的情况下关闭记录集对象?
1)
这个关闭循环内的对象,但在下一个移动时打开一个新对象.如果有1000条记录,则会打开一个对象1000次并关闭1000次.这就是我通常会做的事情:
SQL = " ... "
Set rs1 = conn.Execute(SQL)
While NOT rs1.EOF
SQL = " ... "
Set rs2 = conn.Execute(SQL)
If NOT rs2.EOF Then
Response.Write ( ... )
End If
rs2.Close : set rs2 = Nothing
rs1.MoveNext
Wend
rs1.Close : Set rs1 = Nothing
Run Code Online (Sandbox Code Playgroud)
2)
这个例子就是我想知道的.在循环结束之后保存对象闭包(rs2.close),是获得还是降低性能?如果有1000条记录,这将打开1000个对象但只关闭一次:
SQL = " ... "
Set rs1 = conn.Execute(SQL)
While NOT rs1.EOF
SQL = " ... "
Set rs2 = conn.Execute(SQL)
If NOT rs2.EOF Then
Response.Write ( ... )
End If
rs1.MoveNext
Wend
rs1.Close : Set rs1 = Nothing
rs2.Close : set rs2 = Nothing
Run Code Online (Sandbox Code Playgroud)
我希望我已经很好地解释了自己,并不是太愚蠢.
UPDATE
对于那些认为我的查询可以修改以避免N + 1问题(第二次查询)的人,这里是:
这是一个在线图片库.我有两张桌子; "photoSearch"和"照片".第一个"photoSearch"只有几列,包含照片的所有可搜索数据,例如"photoID","标题","标题","人物","dateCaptured"和"关键字".它有一个多列全文索引(标题,标题,人物,关键字).第二张表"照片"包含所有照片数据; 高度,宽度,版权,标题,ID,日期等等.两者都有500K +行,标题和标题字段有时返回2000+个字符.
这大约是查询现在的样子:(要注意的事项:我不能使用全文搜索的连接,因此关键字存储在一列中 - 在'去规范化'表中.此外,这种伪代码作为我的应用程序代码在其他地方 - 但它很接近)
SQL = "SELECT photoID FROM photoSearch
WHERE MATCH (headline, caption, people, keywords)
AGAINST ('"&booleanSearchStr&"' IN BOOLEAN MODE)
AND dateCaptured BETWEEN '"&fromDate&"' AND '"&toDate&"' LIMIT 0,50;"
Set rs1 = conn.Execute(SQL)
While NOT rs1.EOF
SQL = "SELECT photoID, setID, eventID, locationID, headline, caption, instructions, dateCaptured, dateUploaded, status, uploaderID, thumbH, thumbW, previewH, previewW, + more FROM photos LEFT JOIN events AS e USING (eventID) LEFT JOIN location AS l USING (locationID) WHERE photoID = "&rs1.Fields("photoID")&";"
Set rs2 = conn.Execute(SQL)
If NOT rs2.EOF Then
Response.Write ( .. photo data .. )
End If
rs2.Close
rs1.MoveNext
Wend
rs1.Close
Run Code Online (Sandbox Code Playgroud)
经过测试,在自己的桌子上有全文索引,"photoSearch",而不是大表,"照片",似乎有点提高速度.我没有添加"photoSearch"表,它已经存在 - 这不是我的应用程序.如果我尝试加入这两个表以丢失第二个查询,我会丢失所有索引,导致很长时间 - 所以我不能使用全文连接.这似乎是最快捷的方法.如果不是全文和加入问题,我会将这两个问题结合起来.
事情是这样的。首先,获取你的照片ID并让mysql认为这是一个仅保存照片ID的实际表,然后做出你的实际声明,不需要任何额外的记录集连接...
并且不要忘记从末尾开始执行此操作。这是带有解释的示例代码:
步骤 1创建照片 ID 查找表并命名:这将是我们的 PhotoId 查找表,因此将其命名为“PhotoIds”
SELECT photoID FROM photoSearch
WHERE MATCH (headline, caption, people, keywords)
AGAINST ('"&booleanSearchStr&"' IN BOOLEAN MODE)
AND dateCaptured BETWEEN '"&fromDate&"' AND '"&toDate&"' LIMIT 0,50) AS PhotoIds
Run Code Online (Sandbox Code Playgroud)
步骤 2现在我们有了照片 ID,因此可以从中获取信息。我们将在 WHERE 子句之前插入上述语句,就像处理真实表一样。请注意,我们的“假”表必须位于括号之间。
SQL = "SELECT p.photoID, p.setID, p.eventID, p.locationID, p.headline, p.caption, + more FROM
photos AS p,
events AS e USING (p.eventID),
location AS l USING (p.locationID),
(SELECT photoID FROM photoSearch WHERE MATCH (headline, caption, people, keywords)
AGAINST ('"&booleanSearchStr&"' IN BOOLEAN MODE) AND dateCaptured BETWEEN
'"&fromDate&"' AND '"&toDate&"' LIMIT 0,50) AS PhotoIds
WHERE p.photoID=PhotoIds.photoID;"
Run Code Online (Sandbox Code Playgroud)
注意:我只是在这里编写这些代码,从未测试过。可能存在一些拼写错误或 smt。如果您遇到问题,请告诉我。
现在得到你的主要问题
无需关闭已执行的查询,特别是在使用执行方法时。执行方法在执行后自行关闭,除非它不返回任何记录集数据(这是首先执行命令的目的),例如:“INSERT”、“DELETE”、“UPDATE”。如果您没有打开记录集对象,那么为什么要尝试关闭从未打开过的对象呢?相反,您可以使用Set Rs=Nothing取消引用该对象并将其发送到垃圾回收以释放一些系统资源(这与 mysql 本身无关)。如果您使用“SELECT”查询(将返回一些数据的查询),您必须打开一个记录集对象(ADODB.Recordset),如果您打开它,则需要在它完成其工作后立即将其关闭。
最重要的是在每次页面加载后关闭“与mysql服务器的主连接”。因此,您可以考虑将连接关闭算法(而不是记录集关闭)放入包含文件中,并将其插入到与数据库建立连接的每个页面的末尾。长话短说:如果您使用了Open( ),则必须使用 Close( )