Драйверы sqlsrv медленно работают в коде?
Я установил последнюю версию CI 2.1.3
Теперь, после выполнения запроса, я получаю очень медленное время отклика для чего-то очень простого, такого как:
function Bash(){
$sql = “SELECT * FROM Contacts”;
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
после запроса удаленной базы данных. (SQL Server 2008)
Когда я запускаю этот же запрос в простом скрипте PHP для той же удаленной базы данных. Я получаю результаты мгновенно.
а) Кто-нибудь еще сталкивался с этой проблемой с драйверами sqlsrv в codeigniter?
Если да, то как ты решил это?
Вот моя строка подключения:
$db['default']['hostname'] = "xxxxx,1433";
$db['default']['username'] = "xx";
$db['default']['password'] = "xxxxxx-xx";
$db['default']['database'] = "xxxxxxxxx";
$db['default']['dbdriver'] = "sqlsrv";
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = TRUE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
ОБНОВИТЬ:
Я нашел следующее от запуска профилировщика.
БАЗА ДАННЫХ: база данных: 1 (Скрыть) 0.0659 выбрать * из Контактов
Время загрузки: базовые классы 0.0428 Время выполнения контроллера ( Welcome / AzureBash) 58.2173 Общее время выполнения 58.2602
Кажется, что запрос выполняется за 0,06 секунды, но загрузка контроллера занимает минуту.
Понятия не имею, почему это происходит.
Решение
Интерфейс активных записей для последних драйверов SQLSRV содержит ошибки.
Итак, скачайте и перезапишите существующий интерфейс с помощью этих (перезаписать вашу папку sqlsrv в папке базы данных в CI):
http://www.kaweb.co.uk/blog/mssql-server-2005-and-codeigniter/
Примечание. Они были протестированы с SQL Azure и работают.
$ Query->num_rows(); не работает с этими драйверами, поэтому я предлагаю вам использовать счетчик вместо. Или создайте свою собственную обертку.
Кроме того, date теперь является типом даты в вашем наборе результатов.
Надеюсь, это поможет.
Решение 2
Если по какой-либо причине вы найдете ошибку, которая делает ее совершенно непригодной для использования. Вернитесь к изначально предоставленному интерфейсу sqlsrv. Вы найдете, что причиной проблемы является способ выполнения запроса исходным интерфейсом, таким образом, создайте вспомогательный класс базы данных; использовать $sql = $this->db->last_query(); чтобы получить запрос, который вы собираетесь выполнить, а затем в классе database_helper выполните его самостоятельно:
function MakeDbCall ($sql)
{
$serverName = "xxxxx-xxxx-xxx,1433"; //serverName\instanceName
$connectionInfo = array( "Database"=>"xxx", "UID"=>"xx", "PWD"=>"xxxxx","ConnectionPooling" => "1");
$conn = sqlsrv_connect($serverName,$connectionInfo);
$stmt = sqlsrv_query($conn, $sql);
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$result_array[] = $row;
}
return $result_array;
}
Создать один для row_array.
Вы должны иметь возможность вызывать эту функцию напрямую из любой точки вашего приложения. Пока вы используете способ active_records, создающий ваш запрос.
Не идеальное решение, но пока codeigniter не отсортирует свой класс SQLSRV, мы мало что можем сделать.
5 ответов
Решение
Интерфейс активных записей для последних драйверов SQLSRV содержит ошибки.
Итак, скачайте и перезапишите существующий интерфейс с помощью этих (перезаписать вашу папку sqlsrv в папке базы данных в CI):
http://www.kaweb.co.uk/blog/mssql-server-2005-and-codeigniter/
Примечание. Они были протестированы с SQL Azure и работают.
$ Query->num_rows(); не работает с этими драйверами, поэтому я предлагаю вам использовать счетчик вместо. Или создайте свою собственную обертку.
Кроме того, date теперь является типом даты в вашем наборе результатов.
Решение 2
Если по какой-либо причине вы найдете ошибку, которая делает ее совершенно непригодной для использования. Вернитесь к изначально предоставленному интерфейсу sqlsrv. Вы найдете, что причиной проблемы является способ выполнения запроса исходным интерфейсом, таким образом, создайте вспомогательный класс базы данных; использовать $sql = $this->db->last_query(); чтобы получить запрос, который вы собираетесь выполнить, а затем в классе database_helper выполните его самостоятельно:
function MakeDbCall ($sql)
{
$serverName = "xxxxx-xxxx-xxx,1433"; //serverName\instanceName
$connectionInfo = array( "Database"=>"xxx", "UID"=>"xx", "PWD"=>"xxxxx","ConnectionPooling" => "1");
$conn = sqlsrv_connect($serverName,$connectionInfo);
$stmt = sqlsrv_query($conn, $sql);
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$result_array[] = $row;
}
return $result_array;
}
Создать один для row_array.
Вы должны иметь возможность вызывать эту функцию напрямую из любой точки вашего приложения. Пока вы используете способ active_records, создающий ваш запрос.
Не идеальное решение, но пока codeigniter не отсортирует свой класс SQLSRV, мы мало что можем сделать.
Добавление ответа после того, как ответ уже был принят, потому что я нашел другое решение. У меня была та же проблема... цикл через набор результатов был очень, очень медленным. я открыл system/database/drivers/sqlsrv/sqlsrv_driver.php и нашел функцию подключения. я заметил, что использует параметр SQLSRV_CURSOR_STATIC. я изменил это на SQLSRV_CURSOR_CLIENT_BUFFERED и мои проблемы с медлительностью исчезли. Смотрите документацию для этого здесь:
http://msdn.microsoft.com/en-us/library/hh487160(v=sql.105).aspx
Я, честно говоря, понятия не имею, что делает драйвер сервера sql для php, однако, учитывая скорость и т. Д., Я могу предположить, что драйвер может использовать курсор по умолчанию. это похоже на ужасную идею. Я также предполагаю, что при выборе client_buffered данные для запроса будут прочитаны без курсора и доступны в памяти клиента, как если бы это был курсор. Если это так, могут произойти плохие вещи, если вы попытаетесь выполнить запрос, у которого есть много строк для чтения. Возможно, для чтения данных без курсора можно использовать другую опцию (SQLSRV_CURSOR_FORWARD?), Но я уверен, что методы, используемые для доступа к запросу, будут более ограниченными (например, без использования result_array ())
-Don
Возможно, вы захотите превратить db_debug в FALSE, что должно сэкономить время на отладку базы данных.
Кроме того, предложил бы повернуть cache_on в FALSE и указать cachedir и использовать $this->db->cache_on();
для запросов, которые менее динамичны, то есть не часто меняются.
Какая у вас строка подключения? Вы можете явно указать "сетевой протокол", который иногда может влиять на скорость.
http://www.connectionstrings.com/articles/show/define-sql-server-network-protocol
"Поставщик =sqloledb; Источник данных =190.190.200.100,1433; Сетевая библиотека =DBMSSOCN; Начальный каталог =pubs; Идентификатор пользователя =myUsername; Пароль =myPassword;"
Указывая IP-адрес, номер порта (1433) и сетевую библиотеку, вы предоставляете очень детальную строку подключения. Ваши данные могут отличаться, конечно.
Часто вам это не нужно. Но я был в нескольких поездках клиентов, где это была волшебная пыль.
Для ускорения выборки до 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'
));