PHP SQLSRV 在 sqlsrv_fetch_array/sqlsrv_fetch 上有间歇性延迟

PHP SQLSRV has intermitent delay on sqlsrv_fetch_array/sqlsrv_fetch

我们将数据库连接从 ADODB 切换到 SQLSRV,我似乎遇到了问题,使用 sqlsrv_fetch_array.

导致间歇性延迟

我在我的数据库中查询 returns 大约 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 毫秒。为什么我说它是随机的是因为如果我多次重新运行代码,延迟不会发生在同一个地方并且数量会有所不同,所以这不是因为特定行很大(其中 none无论哪种方式)。

有谁知道我能看到什么可以做到这一点,无论是参数还是某处的配置?我认为这与 server/network 无关,因为 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:严重的速度问题。正如原文 post 中所述,即使循环遍历中等数量的记录(很少 100 秒)也需要一秒钟的时间。

SQLSRV_CURSOR_FORWARD :没有速度问题。循环遍历我示例中的记录需要大约 50 毫秒,这与 ADODB 相同。你失去了做 MoveFirst/MovePrev 的能力,但我认为这很容易解决,如果需要的话,在你的第一次通过时将结果存储在一个数组中,或者根据查询,在极少数情况下重新运行它可能会很好这是必需的。

SQLSRV_CURSOR_CLIENT_BUFFERED :非常快(在我的示例中为 0 毫秒,这是有道理的,因为根据我的理解,它与将整个内容存储在数组中基本相同)。不过,我们在一些较大的数据集中确实存在内存问题。

在我们的项目中,我们最终为 public 网站使用了 SQLSRV_CURSOR_CLIENT_BUFFERED,因为在一个页面中没有提取任何主要数据集,而 SQLSRV_CURSOR_FORWARD 作为后端,您可以在其中结束向上拉取 1000 行数据。