我在PHP(5.5.12)中使用sqlsrv(php_pdo_sqlsrv_55_ts.dll和php_sqlsrv_55_ts.dll)通过VPN隧道连接到MSSQL 2012 Server。但是大结果集的传输速度非常慢。
通过同一VPN隧道在同一台PC上测试此查询的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将不胜感激。
答案 0 :(得分:1)
为了加速提取最多3次,请使用&#34; MultipleActiveResultSets&#34; =&gt;&#39; 0&#39;在sqlsrv_connect连接选项中。
前:
$db = sqlsrv_connect('127.0.0.1', array('Database'=>'dbname','UID'=> 'sa','PWD'=> 'pass',"CharacterSet" =>"UTF-8","ConnectionPooling" => "1"
,"MultipleActiveResultSets"=>'0'
));
答案 1 :(得分:0)
如何更换
$options["Scrollable"] = SQLSRV_CURSOR_CLIENT_BUFFERED;
与
$options["Scrollable"] = SQLSRV_CURSOR_FORWARD;
答案 2 :(得分:0)
最常见的修复方法之一&#34;缓慢的sqlsrv操作是更改可滚动值。我试过这个并没有帮助......实际上SQLSRV_CURSOR_CLIENT_BUFFERED导致了不稳定的行为。
示例:
$stmt = sqlsrv_query( $this->connection, $sql, array(), array(
"Scrollable"=>SQLSRV_CURSOR_CLIENT_BUFFERED
));
我相信较新版本的sqlsrv(我有4.3.0)已经对此进行了一些优化,并怀疑最新版本不需要这样做。
第二个最受欢迎的建议是更改连接选项......我尝试了很多解决方案......他们真的没有帮助。同样,我认为较新的sqlsrv驱动程序已更改此默认设置。
示例:
sqlsrv_configure('ClientBufferMaxKBSize', 0);
$serverName = Config::get('settings.MS_DB_HOST').", 1433";
$connectionInfo = array(
"Database"=>Config::get('settings.MS_DB_NAME'),
"UID"=>Config::get('settings.MS_DB_UID'),
"PWD"=>Config::get('settings.MS_DB_PWD'),
"MultipleActiveResultSets"=>'0',
"connectionpooling"=>"0",
"TraceOn"=>"0"
);
$this->connection = sqlsrv_connect($serverName, $connectionInfo);
所有这一切......最终帮助我的是意识到sqlsrv_connect是我的罪魁祸首,而且速度极慢。对于某些应用程序,您不会注意到这一点......但在我的情况下,我正在处理在执行后续sql操作之前不断重新连接到数据库的代码。所以说这需要半秒才能运行......如果你有10个不同的sql语句,每个语句都是自己连接的&#34; sqlsrv_connect()&#34; ...这个(对我而言)可能需要5秒钟。解决方案是重用第一个实例化中的连接对象。一旦我做到这一点,性能改进是戏剧性的。
希望将来sqlsrv库可以编写像PHP / MySQL持久连接这样的东西,但这不是必需的。