sqlsrv驱动程序在codeigniter中速度慢?

时间:2013-04-08 20:07:39

标签: sql-server codeigniter 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脚本中针对同一个远程数据库运行相同的查询时。我立刻得到了结果。

a)有没有其他人在codeigniter中使用sqlsrv驱动程序遇到此问题?

如果是这样,你是如何解决的?

这是我的连接字符串:

$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 控制器执行时间(欢迎/ AzureBash)58.2173 总执行时间58.2602

似乎查询正在0.06秒内执行,但控制器需要一分钟才能加载。

不知道为什么会这样。

解决方案

最新SQLSRV驱动程序的活动记录界面存在问题。

因此,下载并覆盖现有界面(覆盖CI中数据库文件夹中的sqlsrv文件夹):

http://www.kaweb.co.uk/blog/mssql-server-2005-and-codeigniter/

注意:这些已经过SQL Azure测试并且有效。

$查询 - > NUM_ROWS();不适用于这些驱动程序,所以我建议你改用count。或者创建自己的包装器。

此外,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 个答案:

答案 0 :(得分:3)

<强>解决方案

最新SQLSRV驱动程序的活动记录界面存在问题。

因此,下载并覆盖现有界面(覆盖CI中数据库文件夹中的sqlsrv文件夹):

http://www.kaweb.co.uk/blog/mssql-server-2005-and-codeigniter/

注意:这些已经过SQL Azure测试并且有效。

$查询 - &GT; NUM_ROWS();不适用于这些驱动程序,所以我建议你改用count。或者创建自己的包装器。

此外,date现在是结果集中的日期对象类型。

解决方案2

如果由于某种原因你发现了一个让它完全无法使用的错误。恢复到最初提供的sqlsrv接口。你会发现导致问题的原因是原始接口执行查询的方式,因此,创建一个数据库助手类;使用$ sql = $ this-&gt; db-&gt; 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类进行排序之前,我们无法做很多事情。

答案 1 :(得分:3)

在答案被接受后添加答案,因为我找到了不同的解决方案。我遇到了同样的问题...循环结果集非常慢。我打开了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

老实说,我不知道php的sql server驱动程序是做什么的,但是,考虑到加速等,我可以猜测驱动程序可能默认使用游标。这似乎是个糟糕的主意。我也假设通过选择client_buffered,查询的数据将在没有光标的情况下读取并在客户端的内存中访问,就像它是一个游标一样。如果是这种情况,如果您尝试执行要读取许多行的查询,则可能会发生错误。也许另一个选项(SQLSRV_CURSOR_FORWARD?)可用于在没有游标的情况下读取数据 - 但我确定用于访问查询的方法将更加有限(例如,不使用result_array())

-Don

答案 2 :(得分:1)

你的连接字符串是什么?您可以明确指定“网络协议”,这可能会影响速度。

http://www.connectionstrings.com/articles/show/define-sql-server-network-protocol

“Provider = sqloledb; Data Source = 190.190.200.100,1433; Network Library = DBMSSOCN; Initial Catalog = pubs; User ID = myUsername; Password = myPassword;”

通过指定IP地址,端口号(1433)和网络库,您将提供非常精细的连接字符串。 您的详细信息可能会有所不同。

很多时候,你不需要这个。但我一直在几次客户旅行,这是一个神奇的尘土。

答案 3 :(得分:1)

您可能希望将db_debug变为FALSE,这样可以节省调试数据库的时间。

此外,建议将cache_on设置为FALSE并指定cachedir并使用$this->db->cache_on();用于动态较低的查询,即不会频繁更改。

答案 4 :(得分:0)

要快速提取最多3次,请在sqlsrv_connect连接选项中使用“MultipleActiveResultSets”=&gt;'0'。

前:

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

            ));