小编典典

解决VB6中的ADO超时问题

sql

在VB6中填充ADO记录集时遇到问题。当我使用SSMS运行查询时,查询(命中SQLServer
2008)只需要大约1秒钟即可运行。当结果集很小时,它可以很好地工作,但是当结果集变成几百个记录时,则需要花费很长时间。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事件探查器,并且与SSMS中的两个指标相比,客户端计算机上的实例进行的读取次数更多,花费的时间也增加了100倍。根据探查器,对于SSMS和客户端计算机,查询的文本都是相同的,因此我认为它不应使用其他执行计划。网络库或提供商可能对此有任何影响吗?

探查器统计信息:

  • 从客户端应用程序:读取7041720,持续时间59458 ms,行计数3900
  • 来自SSMS:30802次读取,238 ms持续时间,3900行计数

看起来它正在使用不同的执行计划,但是查询是完全相同的,并且我不确定如何检查客户端可能使用的执行计划(如果它与SSMS中显示的内容不同)。


阅读 231

收藏
2021-04-07

共1个答案

小编典典

800+ records requires about 5 minutes =查询问题。

查看您的执行计划:

在SSMS中,运行:

SET SHOWPLAN_ALL ON

然后运行您的查询,它将不会产生预期的结果集,但是会针对数据库如何检索您的数据制定执行计划。大多数不良查询通常是表扫描(查看表中的每一行,速度很慢),因此请在该StmtText列中查找单词“
SCAN” 。尝试弄清楚为什么未在该表上使用索引(名称将由单词“
SCAN”出现在该表中)。如果您加入多个表并且有多个SCAN,则首先将注意力集中在最大的表上。

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

编辑
从阅读您的问题开始,我不确定您的意思是无论行数多少,它从SSMS总是很快,但是随着行数的增加,它从VB总是慢。

可能类似于:参数嗅探或连接参数不一致(ANSI空值,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 ...
2021-04-07