【问题标题】:sqlsrv drivers slow in codeigniter?sqlsrv 驱动程序在 codeigniter 中运行缓慢?
【发布时间】:2013-04-08 20:07:39
【问题描述】:

我已经安装了最新版本的 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 测试并且可以工作。

$query->num_rows();不适用于这些驱动程序,因此我建议您改用 count。或者创建自己的包装器。

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

我希望这会有所帮助。

解决方案 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 类进行排序之前,我们无能为力。

【问题讨论】:

    标签: sql-server codeigniter sqlsrv


    【解决方案1】:

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

    -唐

    【讨论】:

    • 这对我来说已经足够好了。不知道这可能会产生什么影响。
    • 看来驱动程序将快速(没有光标)循环遍历所有记录并将它们存储在内存数组中。这会很好,直到您有一个返回数千行的查询。在这种情况下,最好跳过代码点火器驱动程序包装器并直接调用 sqlsrv api。这样您就可以循环遍历结果,而无需将所有数据存储在内存中,也无需使用游标。
    • 嗨,Don,我通过找到更好的驱动适配器解决了这个问题:kaweb.co.uk/blog/mssql-server-2005-and-codeigniter。我建议不要直接调用 sqlsrv api,因为它只会导致复杂化(假设您决定切换到另一个具有不同语法的驱动程序,没有包装器,您将花费时间重写您的代码。)。这已经在 azure 上进行了测试并且工作正常。我知道如果您尝试从本地计算机连接到 Web 服务器会有点慢,但我想这是一个延迟问题。而不是驱动问题。希望对您有所帮助。
    【解决方案2】:

    解决方案

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

    所以,下载并用这些覆盖现有接口(覆盖 CI 中数据库文件夹中的 sqlsrv 文件夹):

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

    注意:这些已经通过 SQL Azure 测试并且可以工作。

    $query->num_rows();不适用于这些驱动程序,因此我建议您改用 count。或者创建自己的包装器。

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

    解决方案 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 类进行排序之前,我们无能为力。

    【讨论】:

      【解决方案3】:

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

      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) 和网络库,您可以提供非常精细的连接字符串。 当然,您的详细信息可能会有所不同。

      很多时候,你不需要这个。但我参加过几次客户旅行,这就是神奇的尘埃。

      【讨论】:

      • 看起来他们没有为 network_library 提供挂钩。 :ellislab.com/forums/viewthread/205186/#966443 microsoft.com/en-us/download/details.aspx?id=20098 但基本上,我不知道......只是想帮忙。
      • 您可以“回答自己的问题”并将其标记为“答案”,仅供参考。不是“去”的举动,但如果你找到了答案,那就去做吧。而且,它会被网站标记为“已解决”,因此人们不会一直将其视为未回答的问题。 . PS并且您可以在此处将任何答案标记为“有帮助”。 (只是说)。
      • 向上和向下箭头,单击“向上”箭头。每个帖子都会有一个相应的向上和向下箭头。 (每个帖子的左上角)。
      • 我刚刚对你的答案投了赞成票。在您的答案上应该有一个大的“检查”图标,您可以将其标记为“最佳解决方案”。我不记得了,您可能需要等待几天才能将自己的答案选为“最佳解决方案”,以防止人们人为地夸大自己的声誉。
      【解决方案4】:

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

      另外,建议将 cache_on 设置为 FALSE 并指定 cachedir 并将 $this->db->cache_on(); 用于不太动态的查询,即不经常更改。

      【讨论】:

      • 做了修改,见上。顺便说一句,这没有用,但是谢谢。
      • 是的,请参阅我的原始帖子进行修改。
      【解决方案5】:

      为了将获取速度提高 3 倍,请在 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'
      
                  ));
      

      【讨论】:

        猜你喜欢
        • 2012-08-03
        • 2018-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-04
        • 2012-06-09
        • 2017-09-15
        相关资源
        最近更新 更多