升级到SQL Server 2012后的select count(*)查询奇怪的偶发性能问题(从2005年开始)

时间:2016-04-29 06:34:08

标签: sql-server sql-server-2012 ado

我们有一个原生的C ++ COM应用程序来控制我们的生产线。该应用程序使用ADO访问MS SQL服务器。应用程序的服务器部分在Windows Server 2003和Clients XP上运行。最近我们从SQL SERVER 2005切换到SQL SERVER 2012(但数据库保留在2005兼容模式中)。迁移非常顺利(只有1/2停机时间)。旧服务器和客户端位于同一个域中,新服务器位于不同的域中(当然是受信任的)。身份验证由SQL Server身份验证完成。然而,现在我抱怨有关包装客户站上特定操作的零星性能降级。通过将一些调试输出放入代码中,我可以找到所涉及的代码,并且此代码执行“从TableX中选择count(*),其中col =?”查询(未准备好)。桌子有最大值。几千个条目以及列索引的位置。提交隔离级别读取。阻止不应该是一个问题,因为只有单行的更新和插入。但即使是大规模更新也不应该成为一千行的问题。

此查询大多数时间以毫秒为单位执行,但有时需要大约10秒。这是用于执行SQL语句的代码块。

HRESULT CCxADORecordset::OpenSQL(CString strSQL, CursorTypeEnum eCursorType, LockTypeEnum eLockType)
{
HRESULT hr = S_OK;
CCxDataLogger dataLogger("CxDBServerLib");

CString strDebug;
strDebug.Format("CCxADORecordset::OpenSQL2: BeforeGetRecordSet (%s)\n", strSQL);
OutputDebugString(strDebug);

SET_SUCC_HR(hr, GetRecordset());

COleVariant varSQL(strSQL);

bool fFinished = false;
long lRetryCount = 1;

do
{
    OutputDebugString("CCxADORecordset::OpenSQL2: BeforeOpen\n");
    SET_SUCC_HR(hr, m_pIRecordset->Open(varSQL, g_varEmpty, eCursorType, eLockType, adCmdText));

    OutputDebugString("CCxADORecordset::OpenSQL2: BeforeGetExecuteRetry\n");

LockType和CursorType可以由注册表项配置,并设置为adLockOptimistic和adOpenKeyset。

这是一些示例调试输出

01308272    13:46:24.701    [2964] CCxADORecordset::OpenSQL: BeforeGetDefaultCursorType
01308273    13:46:24.701    [2964] CCxADORecordset::OpenSQL: BeforeGetDefaultLockType
01308274    13:46:24.701    [2964] CCxADORecordset::OpenSQL: BeforeOpenSQL2
01308275    13:46:24.701    [2964] CCxADORecordset::OpenSQL2: BeforeGetRecordSet (SELECT Count(*) As lCount              FROM ProdArtikel        WHERE lWTNr = -2)
01308276    13:46:24.701    [2964] CCxADORecordset::OpenSQL2: BeforeOpen
01308277    13:46:33.717    [2964] CCxADORecordset::OpenSQL2: BeforeGetExecuteRetry
01308278    13:46:33.717    [2964] CCxADORecordset::OpenSQL2: AfterGetExecuteRetry
01308279    13:46:33.717    [2964] CCxADORecordset::OpenSQL: AfterOpenSQL2
01308280    13:46:33.717    [2964] CommonHelper::isWTEmpty() Before getFieldValue
01308281    13:46:33.717    [2964] CommonHelper::isWTEmpty() Before Close

并且仅在几毫秒之后

01308300    13:46:33.732    [2964] CCxADORecordset::OpenSQL: BeforeGetDefaultCursorType
01308301    13:46:33.732    [2964] CCxADORecordset::OpenSQL: BeforeGetDefaultLockType
01308302    13:46:33.732    [2964] CCxADORecordset::OpenSQL: BeforeOpenSQL2
01308303    13:46:33.732    [2964] CCxADORecordset::OpenSQL2: BeforeGetRecordSet (SELECT Count(*) As lCount              FROM ProdArtikel        WHERE lWTNr = -2)
01308304    13:46:33.732    [2964] CCxADORecordset::OpenSQL2: BeforeOpen
01308305    13:46:33.748    [2964] CCxADORecordset::OpenSQL2: BeforeGetExecuteRetry
01308306    13:46:33.748    [2964] CCxADORecordset::OpenSQL2: AfterGetExecuteRetry
01308307    13:46:33.748    [2964] CCxADORecordset::OpenSQL: AfterOpenSQL2
01308308    13:46:33.748    [2964] CommonHelper::isWTEmpty() Before getFieldValue
01308309    13:46:33.748    [2964] CommonHelper::isWTEmpty() Before Close

似乎只有这个查询有时会出现性能问题。

我为没有帮助的数据库激活了快照隔离级别。我激活了SQL Server扩展事件(阻塞进程阈值设置为5秒)以生成阻止的进程报告。它没有创建任何输出。

我运行SQL Server跟踪。对于语句的第一次和第二次执行,它显示相同的SQL执行时间0 ms。

SQL:BatchStarting                   SELECT Count(*) As lCount                  FROM ProdArtikel                    WHERE lWTNr = -2 CxFrame     2964    DEL10   sigma           256 2016-04-28 13:46:25.697             LINIE10-4   16      22078966    1       0XAF4C8D9B17C7A24FB9D948FA565A9898      0       ZDELINESQL2\DEPRODUCTION    sigma       0                                   
SQL:StmtCompleted   0   2016-04-28 13:46:25.697         SELECT Count(*) As lCount                  FROM ProdArtikel                    WHERE lWTNr = -2 CxFrame 0   2964    DEL10   sigma       2   256 2016-04-28 13:46:25.697 0           LINIE10-4                                                                                       
SQL:BatchCompleted  0   2016-04-28 13:46:25.697         SELECT Count(*) As lCount                  FROM ProdArtikel                    WHERE lWTNr = -2 CxFrame 0   2964    DEL10   sigma       2   256 2016-04-28 13:46:25.697 0           LINIE10-4   16  0 - OK  22078967    1       0XAF4C8D9B17C7A24FB9D948FA565A9898      0   1   ZDELINESQL2\DEPRODUCTION    sigma       0           

SQL:BatchStarting                   SELECT Count(*) As lCount                  FROM ProdArtikel                    WHERE lWTNr = -2 CxFrame     2964    DEL10   sigma           256 2016-04-28 13:46:34.743             LINIE10-4   16      22079361    1       0XAF4C8D9B17C7A24FB9D948FA565A9898      0       ZDELINESQL2\DEPRODUCTION    sigma       0                                   
SQL:StmtCompleted   0   2016-04-28 13:46:34.747         SELECT Count(*) As lCount                  FROM ProdArtikel                    WHERE lWTNr = -2 CxFrame 0   2964    DEL10   sigma       2   256 2016-04-28 13:46:34.747 0           LINIE10-4                                                                                       
SQL:BatchCompleted  0   2016-04-28 13:46:34.743         SELECT Count(*) As lCount                  FROM ProdArtikel                    WHERE lWTNr = -2 CxFrame 0   2964    DEL10   sigma       2   256 2016-04-28 13:46:34.743 0           LINIE10-4   16  0 - OK  22079362    1       0XAF4C8D9B17C7A24FB9D948FA565A9898      0   1   ZDELINESQL2\DEPRODUCTION    sigma       0                                   

我现在已经脱离了我的可能性。我不知道该怎么办。我当然不能改回SQL SERVER 2005。我不怀疑netwerk问题,因为客户端没有更改,新的SERVER也位于与旧服务器相同的数据中心。新旧服务器都在VMWare上虚拟化。

我该怎么办?用户现在住了大约6周就有这个问题(很耐心)。我可以进一步调试 - >打开ADO调用吗?网络监视器会有帮助吗?请提出建议?

问候,Jörg

0 个答案:

没有答案