【发布时间】:2014-12-18 18:12:38
【问题描述】:
我在 PHP (5.5.12) 中使用 sqlsrv(php_pdo_sqlsrv_55_ts.dll 和 php_sqlsrv_55_ts.dll)通过 VPN 隧道连接到 MSSQL 2012 服务器。但是大型结果集的传输速度非常慢。
为此查询在同一台 PC 上通过同一 VPN 隧道测试 SSMS:
SELECT *
FROM [Data].[dbo].[Logins]
WHERE date >= '2014-01-27 00:00:00.000' AND date < '2014-01-29 00:00:00.000'
在 4 秒内返回大约 100,000 行。在查询运行时检查我的防火墙/VPN 上的传输速率显示为 2,500 KB/s(在 100mbit 网络上)。
使用 PHP:
sqlsrv_configure('ClientBufferMaxKBSize', 1024*1024);
$dbconnect = "SERVER\\HERE";
$dbconinfo = array("UID" => "user", "PWD" => "pass", "Database" => "Data")
$conn = sqlsrv_connect( $dbconnect, $dbconinfo);
$sql = "
SELECT *
FROM [dbo].[Logins]
WHERE date >= '2014-01-27 00:00:00.000' AND date < '2014-01-29 00:00:00.000'
";
$options = array();
$options["Scrollable"] = SQLSRV_CURSOR_CLIENT_BUFFERED;
$options["QueryTimeout"] = 30000;
$stmt = sqlsrv_query( $conn, $sql, array(), $options);
运行 40 秒,并且在查询运行时防火墙/VPN 显示低于 150 KB/s。任务管理器显示脚本大约 5% 的 CPU。
我使用 SQLSRV_CURSOR_CLIENT_BUFFERED 只是为了测试,因为它在没有任何 PHP 代码的情况下在自己的缓冲区中读取结果。在没有缓冲的情况下获取每组数据只是稍微慢一点(大约 45 秒)。
我也尝试了导致相同结果的 PDO 版本。
ConnectionPooling 0 或 1 也没有任何区别。
将服务器名称更改为 DNS 与 IP 地址也没有区别。
LogSubsystems -1 和 LogSeverity -1 没有显示任何问题或任何有用的信息。
我什至使用 Wireshark 来观察网络流量,但找不到 PHP 和 SSMS 版本之间的任何大差异。但我对网络层了解不多。
任何想法可能是什么问题或我可以尝试加速 PHP/sqlsrv 的任何想法将不胜感激。
【问题讨论】:
-
添加更多调试。为代码中的每个 db 调用计时。如果每个呼叫都同样慢,那么它可能与网络有关。如果它只是一个调用(例如连接),那么它是特定于该调用的。
-
我用相同的结果测试了其他查询。看起来我不能让 sqlsrv 超过 150 KB/s,而 SSMS 快 10 倍。知道我可以通过网络检查什么吗?因为 SSMS 使用完全相同的连接。
-
我对网络了解不多,但是从 SQL 方面,您可以尝试将结果集缩减为仅需要的数据。去掉
SELECT *,只列出需要的字段。 -
这只是一个测试查询来表明这一点。所有具有大型结果集的 PHP/sqlsrv 查询都非常慢,比 Management Studio 中来自同一台 PC 的完全相同的查询慢 10-15 倍。我不知道为什么。 (如果我使用本地测试 SQL 服务器,PHP 实际上比 SSMS 快,但在网络上它非常慢)
标签: php sql-server networking sqlsrv