我们将数据库连接从 ADODB 切换到 SQLSRV,我似乎遇到了问题,导致使用 sqlsrv_fetch_array 出现间歇性延迟。
我在我的数据库中执行查询,返回大约 426 行和 5 个字段。
代码看起来像这样(出于速度基准的目的,我真的删除了它正在做的任何其他事情):
$conn = sqlsrv_connect( $host, array("UID"=>$userName,"PWD"=>$password,"Database"=>$dbName,"QuotedId"=>false, "CharacterSet" =>"UTF-8");
$rsText=sqlsrv_query($conn,$sqlStr,array(),
array(
"Scrollable"=>SQLSRV_CURSOR_STATIC
));
$row = array(1);
while(count($row) != 0){
$row=sqlsrv_fetch_array($rsText,SQLSRV_FETCH_BOTH, SQLSRV_SCROLL_NEXT);
}
使用 ADODB 运行它需要大约 50 毫秒。使用 sqlsrv 运行它需要 500-1000 毫秒。使用 sqlsrv 的原始查询 (sqlsrv_query) 实际上比 ADODB 更快,但是使用 sqlsrv_fetch_array 存在随机时间延迟(我实际上使用 sqlsrv_fetch 进行了测试并且也得到了它们)。我每次调用它时都以毫秒为单位计时,虽然每次调用通常为 0-1 毫秒,但有时会达到 15 毫秒。为什么我说它是随机的是因为如果我多次重新运行代码,延迟不会发生在同一个地方并且数量会有所不同,所以这不是因为特定的行很大(它们都不是) .
有没有人知道我能看到什么可以做到这一点,无论是某个地方的参数还是配置?我不认为它与服务器/网络相关,因为 ADODB 从来没有这样做过。我们使用 PHP 5.6 和 php_sqlsrv_56_ts.dll/php_pdo_sqlsrv_56_ts.dll 和 SQL Server 2008。
谢谢!
最佳答案
按照 alalp 在评论中的建议,我尝试修改滚动类型并解决了问题。
我做了一些快速基准测试,这是我得到的结果:
SQLSRV_CURSOR_STATIC、SQLSRV_CURSOR_KEYSET 和 SQLSRV_CURSOR_DYNAMIC:严重的速度问题。如原帖所述,即使循环遍历中等数量的记录(几百条)也需要一秒钟的时间。
SQLSRV_CURSOR_FORWARD:没有速度问题。循环遍历我示例中的记录需要大约 50 毫秒,这与 ADODB 相同。您失去了执行 MoveFirst/MovePrev 的能力,但我认为这很容易解决,如果需要,可以通过在第一次传递时将结果存储在数组中,或者根据查询,在极少数情况下重新运行它可能会很好需要。
SQLSRV_CURSOR_CLIENT_BUFFERED:速度极快(在我的示例中为 0 毫秒,这是有道理的,因为根据我的理解,这与将整个内容存储在数组中基本相同)。不过,我们在一些较大的数据集中确实存在内存问题。
在我们的项目中,我们最终对公共(public)网站使用了 SQLSRV_CURSOR_CLIENT_BUFFERED,因为在一个页面中从未提取过任何主要数据集,而对后端使用 SQLSRV_CURSOR_FORWARD,您最终可以提取 1000 行数据。
关于PHP SQLSRV 在 sqlsrv_fetch_array/sqlsrv_fetch 上有间歇性延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36869716/