sqlsrv очень медленный по сети

Я использую sqlsrv (php_pdo_sqlsrv_55_ts.dll и php_sqlsrv_55_ts.dll) в PHP (5.5.12) для подключения к серверу MSSQL 2012 через VPN-туннель. Но скорость передачи для больших наборов результатов очень медленная.

Тестирование SSMS на том же ПК через тот же VPN-туннель для этого запроса:

SELECT *
FROM [Data].[dbo].[Logins]
WHERE date >= '2014-01-27 00:00:00.000' AND date < '2014-01-29 00:00:00.000'

возвращает около 100 000 строк за 4 секунды. Проверка скорости передачи данных на моем брандмауэре / VPN показывает 2500 КБ / с (в сети 100 Мбит) во время выполнения запроса.

Используя 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 КБ / с во время выполнения запроса. Диспетчер задач показывает около 5% процессорного времени для скрипта.

Я использовал SQLSRV_CURSOR_CLIENT_BUFFERED только для тестирования, потому что он считывает результат в свой собственный буфер без какого-либо дополнительного кода PHP. Выборка каждого набора данных без буферизации происходит немного медленнее (около 45 секунд).

Я также попробовал версию PDO, которая привела к тому же самому результату.

ConnectionPooling 0 или 1 также не имеет никакого значения.

Изменение имени сервера на DNS или IP-адрес также не имело значения.

LogSubsystems -1 и LogSeverity -1 не показали никаких проблем или чего-либо полезного вообще.

Я даже использовал Wireshark для наблюдения за сетевым трафиком, но не смог найти больших различий между версиями PHP и SSMS. Но я не знаю слишком много о сетевых уровнях.

Будем весьма благодарны за любые идеи, что может быть проблемой или что я мог бы попытаться ускорить PHP / sqlsrv.

2

Решение

Для ускорения выборки до 3 раз, пожалуйста, используйте «MultipleActiveResultSets» => ‘0’ в параметрах подключения sqlsrv_connect.

Пример:

$db = sqlsrv_connect('127.0.0.1', array('Database'=>'dbname','UID'=> 'sa','PWD'=> 'pass',"CharacterSet" =>"UTF-8","ConnectionPooling" => "1","MultipleActiveResultSets"=>'0'

));
1

Другие решения

Как насчет замены

$options["Scrollable"] = SQLSRV_CURSOR_CLIENT_BUFFERED;

с

$options["Scrollable"] = SQLSRV_CURSOR_FORWARD;
0

Одним из наиболее распространенных «исправлений» медленных операций 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, каждый из которых подключается к своему собственному «sqlsrv_connect ()» … это (для меня) может занять 5 секунд. Решение состояло в том, чтобы повторно использовать объект подключения из первого экземпляра. Как только я это сделал, улучшения производительности были впечатляющими.

Надеемся, что в будущем библиотека sqlsrv запрограммирует что-то вроде постоянных соединений PHP / MySQL, и в этом нет необходимости.

0
По вопросам рекламы [email protected]