sqlsrv驱动程序在codeigniter中运行缓慢?

jv2fixgn  于 8个月前  发布在  其他
关注(0)|答案(5)|浏览(89)

我已经安装了最新版本的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控制器执行时间(Welcome / AzureBash)58.2173总执行时间58.2602
看起来好像查询在0.06秒内执行,但控制器需要一分钟才能加载。
不知道为什么会这样。

解决方案

最新的SQLSRV驱动程序的活动记录接口有缺陷。
因此,下载并使用以下内容覆盖现有接口(覆盖CI中数据库文件夹中的sqlsrv文件夹):
http://www.kaweb.co.uk/blog/mssql-server-2005-and-codeigniter/
注意:这些都已经过SQL Azure测试,可以正常工作。
$query->num_rows();不适用于这些驱动程序,因此我建议您使用count。或者创建自己的 Package 。
此外,date现在是结果集中的日期对象类型。
我希望这能帮上忙。

方案二

如果因为任何原因你发现了一个错误,使这个完全无法使用。恢复到最初提供的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类进行排序之前,我们也没有太多可以做的事情。

jucafojl

jucafojl1#

在答案已经被接受之后添加一个答案,因为我找到了不同的解决方案。我也有同样的问题...循环遍历结果集非常非常慢。我打开了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())

zz2j4svz

zz2j4svz2#

解决方案

最新的SQLSRV驱动程序的活动记录接口有缺陷。
因此,下载并使用以下内容覆盖现有接口(覆盖CI中数据库文件夹中的sqlsrv文件夹):
http://www.kaweb.co.uk/blog/mssql-server-2005-and-codeigniter/
注意:这些都已经过SQL Azure测试,可以正常工作。
$query->num_rows();不适用于这些驱动程序,因此我建议您使用count。或者创建自己的 Package 。
此外,date现在是结果集中的日期对象类型。

方案二

如果因为任何原因你发现了一个错误,使这个完全无法使用。恢复到最初提供的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类进行排序之前,我们也没有太多可以做的事情。

72qzrwbm

72qzrwbm3#

您的连接字符串是什么?您可以明确指定“网络协议”,这有时会影响速度。
http://www.connectionstrings.com/articles/show/define-sql-server-network-protocol
“Provider=sqloledb;数据源= 190.190.200.100,1433;网络库=DBMSSOCN;初始目录=pubs;用户ID=myUsername; Password=myPassword;“
通过指定IP地址、端口号(1433)和网络库,您提供了一个非常精细的连接字符串。当然,您的详细信息可能会有所不同。
很多时候,你不需要这个。但我有几次客户出差时发现这就是神奇之尘。

z8dt9xmd

z8dt9xmd4#

您可能希望将db_debug设置为debug,这样可以保存调试数据库的时间。
此外,建议将cache_on设置为cachedir,并指定cachedir,并对动态性较低的查询使用$this->db->cache_on();,即不会经常改变。

vnzz0bqm

vnzz0bqm5#

为了加快读取速度,请在sqlsrv_connect连接选项中使用"MultipleActiveResultSets"=>'0'
例如:

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

相关问题