4

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 サーバー 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;

アップデート:

プロファイラーを実行すると、次のことがわかりました。

DATABASE: データベース QUERIES: 1 (非表示) 0.0659 select * from Contacts

読み込み時間: 基本クラス 0.0428 コントローラー実行時間 ( Welcome / AzureBash ) 58.2173 合計実行時間 58.2602

クエリは 0.06 秒で実行されているように見えますが、コントローラーの読み込みには 1 分かかります。

なぜこれが起こっているのか分かりません。

解決

最新の 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 クラスをソートするまで、できることはあまりありません。

4

5 に答える 5

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サーバードライバーが何をしているのかわかりませんが、スピードアップなどを考えると、ドライバーがデフォルトでカーソルを使用している可能性があると推測できます。これはひどい考えのようです。また、client_buffered を選択すると、クエリのデータがカーソルなしで読み取られ、クライアントのメモリ内でカーソルのようにアクセスされると想定しています。この場合、読み取る行が多数あるクエリを実行しようとすると、問題が発生する可能性があります。おそらく別のオプション (SQLSRV_CURSOR_FORWARD?) を使用して、カーソルなしでデータを読み取ることができますが、クエリへのアクセスに使用される方法はより制限されると確信しています (たとえば、result_array() を使用しない)。

-ドン

于 2013-05-28T15:54:58.360 に答える
3

解決

最新の 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 クラスをソートするまで、できることはあまりありません。

于 2013-04-10T13:57:18.117 に答える
1

db_debug を FALSE に変更すると、データベースのデバッグ時間を節約できます。

また、cache_on を FALSE に設定し、cachedir を指定$this->db->cache_on();して、あまり動的でない、つまり頻繁に変更されないクエリに使用することをお勧めします。

于 2013-04-09T17:18:48.680 に答える
1

接続文字列は何ですか? 「ネットワークプロトコル」を明示的に指定できますが、これは速度に影響を与えることがあります。

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

"プロバイダー = sqloledb;データ ソース = 190.190.200.100,1433;ネットワーク ライブラリ = DBMSSOCN;初期カタログ = pubs;ユーザー ID = myUsername;パスワード = myPassword;"

IP アドレス、ポート番号 (1433)、およびネットワーク ライブラリを指定することにより、非常に詳細な接続文字列を提供します。もちろん、詳細は異なる場合があります。

多くの場合、これは必要ありません。しかし、私はこれが魔法の粉だったいくつかのクライアント旅行に行ってきました.

于 2013-04-08T21:20:43.597 に答える
0

フェッチを最大 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'

            ));
于 2014-12-19T21:04:46.753 に答える