SQL Native Client 10性能不佳(由于服务器端游标)
我们有一个应用程序在MFC(VS2010)中通过C
Database / CRecordset使用ODBC.
我们实施了两个后端. MSSQL和 MySQL. 现在,当我们使用MSSQL(使用Native Client 10.0)时,使用SELECT检索记录通过慢速链接(例如VPN)非常慢. MySQL ODBC驱动程序没有表现出这种令人讨厌的行为. 例如: CRecordset r(&m_db); r.Open(CRecordset::snapshot,L"SELECT a.something,b.sthelse FROM TableA AS a LEFT JOIN TableB AS b ON a.ID=b.Ref"); r.MoveFirst(); while(!r.ISEOF()) { // Retrieve CString strData; crs.GetFieldValue(L"a.something",strData); crs.MoveNext(); } 现在,使用MySQL驱动程序,一切都按预期运行.返回查询,一切都闪电般快. 我认为这是由于服务器端游标,但我没有找到一种方法来禁用它们.我试过用过: ::SQLSetConnectAttr(m_db.m_hdbc,SQL_ATTR_ODBC_CURSORS,SQL_CUR_USE_ODBC,SQL_IS_INTEGER); 但这也没有帮助. SQL Profiler中的sp_cursorfetch()等仍有长期运行的exec. 问题1:是否有可能以某种方式让本机客户端“缓存”所有结果本地使用本地游标的方式与MySQL驱动程序似乎一样? 也许这是完全错误的方法,但我不确定如何做到这一点. 我们想要的只是从SELECT中一次检索所有数据,然后再不谈论服务器直到下一个查询. 问题2:有没有更有效的方法来使用ODBC在MFC中检索数据? 解决方法我对这个问题进行了修改,发现了这两个链接:MSDN Link MSDN Blog 在第一个链接中,它描述了仅当更改默认选项时,Native Client 10才使用服务器端游标:
Link 2是一个博客,它是一个SQL Dev博客,它说:
是的,当然这是出乎意料的……
现在,解决方案的实施是这样的: 代替: // crs is a CRecordSet crs.Open(CRecordset::snapshot,L"SELECT something..."); 做这个: // crs is a CRecordSet crs.Open(CRecordset::forwardOnly,L"SELECT something..."); 这个简单的更改不会触发创建服务器端游标,并模仿MySQL驱动程序的行为. 缺点是现在您无法通过(Microsoft推荐)方式检索行计数: while(crs.MoveNext()) nCount++; 无论如何,这是一个坏主意.此外,:: SQLGetRowCount()将不再一直有效. 我已经解决了这个问题(这应该适用于任何ANSI兼容的SQL源): //strQuery is the random query passed to CountRows() std::wstringstream ssQuery; ssQuery << L"SELECT COUNT(*) AS Count FROM (" << strQuery << L") AS t"; CRecordset crs(&m_Database); crs.Open(CRecordset::forwardOnly,ssQuery.str().c_str()); // Now retrieve the only "Count" field from the recordset. 我希望将来可以帮助别人. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |