在VB6中解决ADO超时问题

5

我在使用VB6中的ADO记录集填充时遇到了问题。查询(命中SQLServer 2008)仅需要约1秒钟即可在SSMS中运行。当结果集很小时,它可以正常工作,但是当它变成几百条记录时,它会花费很长时间。800多条记录需要大约5分钟才能返回(查询在SSMS中仍然只需1秒钟),而6000多条记录则需要超过20分钟。我通过增加命令超时时间“修复”了异常,但我想知道是否有一种方法可以使其运行更快,因为似乎不是实际查询需要这么长时间。例如压缩结果以减少所需时间等。记录集的打开方式如下:

myConnection.CommandTimeout = 2000
myConnection.ConnectionString = "Provider=SQLOLEDB;" & _
        "Initial Catalog=DB_NAME;" & _
        "Data Source=SERVER_NAME" & _
        "Network Library=DBMSSOCN;" & _
        "User ID=USER_NAME;" & _
        "Password=PASSWORD;" & _
        "Use Encryption for Data=True;"
myConnection.Open

myRecordSet.Open STORED_PROC_QUERY_STRING, myConnection, adOpenStatic, adLockReadOnly
Set myRecordSet.ActiveConnection = Nothing

myConnection.Close

数据返回3列用于填充组合框。
更新: 我运行了SQL Profiler,并且从客户端机器发出的实例读取更多数据,并且用时是在SSMS中查询的两个指标的100倍。根据分析器,查询的文本对于SSMS和客户端机器是相同的,因此我认为它不应该使用不同的执行计划。网络库或提供程序会对此产生任何影响吗?
Profiler统计信息:
- 来自客户端应用程序:7041720次读取,59458毫秒持续时间,3900行计数 - 来自SSMS:30802次读取,238毫秒持续时间,3900行计数
看起来它正在使用不同的执行计划,但查询完全相同,我不确定如何检查客户端可能正在使用的执行计划是否与在SSMS中显示的执行计划不同。

你尝试过移除“使用数据加密”吗? - Andomar
1
你尝试过对调用进行分析并查看执行计划,以验证这绝对不是参数嗅探问题吗? - Martin Smith
1
你正在将一个下拉框填充6000条记录吗? - StingyJack
如果您正在使用6000行填充组合框,则需要设计更好的用户界面(将其过滤为可管理的数量)。 - KM.
这个问题中,有人解决了一个听起来类似的问题。它有帮助吗? - MarkJ
显示剩余3条评论
1个回答

3

800+条记录需要约5分钟 = 查询问题。

查看执行计划:

在SSMS中运行:

SET SHOWPLAN_ALL ON

然后运行查询,它不会产生预期的结果集,而是一个关于数据库如何检索数据的执行计划。大多数糟糕的查询通常会进行表扫描(查看表中的每一行,这很慢),因此请查找StmtText列中的“SCAN”单词。尝试弄清楚为什么该表上的索引未被使用(该表的名称将由“SCAN”一词标识)。如果您加入了多个表并且有多个SCAN,请先集中处理最大的表。

没有更多的信息,这是您可以得到的最好的“通用”帮助。

编辑
从阅读您的问题,我不确定您是否意味着无论行数如何,它都始终从SSMS快速,但是从VB慢。如果是这种情况,请检查以下内容:http://www.google.com/search?q=sql+server+fast+from+ssms+slow+from+application&hl=en&num=100&lr=&ft=i&cr=&safe=images

可能是参数嗅探或不一致的连接参数(ANSI nulls、arithabort等)之类的问题。

对于连接设置,请尝试从SSMS和VB6中运行这些内容(将它们添加到结果集中),并查看是否有任何差异:

SELECT SESSIONPROPERTY ('ANSI_NULLS') --Specifies whether the SQL-92 compliant behavior of equals (=) and not equal to (<>) against null values is applied.
                                      --1 = ON 
                                      --0 = OFF

SELECT SESSIONPROPERTY ('ANSI_PADDING') --Controls the way the column stores values shorter than the defined size of the column, and the way the column stores values that have trailing blanks in character and binary data.
                                        --1 = ON 
                                        --0 = OFF

SELECT SESSIONPROPERTY ('ANSI_WARNINGS') --Specifies whether the SQL-92 standard behavior of raising error messages or warnings for certain conditions, including divide-by-zero and arithmetic overflow, is applied.
                                         --1 = ON 
                                         --0 = OFF

SELECT SESSIONPROPERTY ('ARITHABORT') -- Determines whether a query is ended when an overflow or a divide-by-zero error occurs during query execution.
                                      --1 = ON 
                                      --0 = OFF

SELECT SESSIONPROPERTY ('CONCAT_NULL_YIELDS_NULL') --Controls whether concatenation results are treated as null or empty string values.
                                                    --1 = ON 
                                                    --0 = OFF

SELECT SESSIONPROPERTY ('NUMERIC_ROUNDABORT') --Specifies whether error messages and warnings are generated when rounding in an expression causes a loss of precision.
                                              --1 = ON 
                                              --0 = OFF

SELECT SESSIONPROPERTY ('QUOTED_IDENTIFIER') --Specifies whether SQL-92 rules about how to use quotation marks to delimit identifiers and literal strings are to be followed.
                                             --1 = ON 
                                             --0 = OFF

请按以下方式进行查询(以便您可以在VB6中查看连接设置):

SELECT
    col1, col2
        ,SESSIONPROPERTY ('ARITHABORT') AS ARITHABORT
        ,SESSIONPROPERTY ('ANSI_WARNINGS') AS ANSI_WARNINGS
    FROM ...

根据原帖,查询在 SSMS 中运行时间不到一秒钟。查询的文本完全相同(已通过 SQL Profiler 确认)。我查看了执行计划,看起来很好。所有索引都被使用了。 - Bryant Bowman
真的值得比较上述会话属性,因为它们可能会影响性能。至少在发出 SET ARITHABORT ON 后尝试 ADO 查询。 - Alex K.
这是arithabort属性。感谢您的帮助。 - Bryant Bowman
我在数据库层面上更改了设置。我认为几天前可能已经被重置了,这突然引起了这个问题。我最好的猜测是在我们重新启动服务器时它被重置了。 - Bryant Bowman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接