2016-12-18 14 views
0

私は、CodeIgniter3ライブラリを使用してMySQLデータベースに簡単なクエリを作成する際に問題に直面しています。私はボトルネックを見つける問題に直面しており、あなたの意見を聞きたい。CodeIgniter3およびresults_array()タイムアウト

技術仕様:

  • PHP 5.4
  • のCodeIgniter 3.1.2
  • のMySQL 5.1.73

(/var/lib/mysql.sock経由) 表 '通知':

mysqlの中から
+-------------+--------------+------+-----+------------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+--------------+------+-----+------------+----------------+ 
| id   | int(11)  | NO | PRI | NULL  | auto_increment | 
| receiver_id | int(11)  | NO | MUL | 0   |    | 
| content  | varchar(254) | NO |  | NULL  |    | 
| created  | varchar(10) | NO |  | 1000000000 |    | 
| seen  | set('0','1') | NO |  | 0   |    | 
+-------------+--------------+------+-----+------------+----------------+ 
5 rows in set (0.01 sec) 

直接クエリ:CodeIgniterので

mysql> select * from notifications order by created desc limit 100; 
... 
... 
100 rows in set (0.01 sec) 

問合せ:

// Load User's Notifications 
public function LoadNotifications($UserID) 
{ 
    // Load Replies 
    $sql   = "SELECT id, content, created, seen FROM notifications WHERE receiver_id=$UserID ORDER BY created DESC LIMIT 100"; 
    $query   = $this->db->query($sql); 
    if($query->num_rows() == 0) return '0'; 
    $results  = $query->result_array(); 
    return $results; 
} 

私の観察とその理由を見つけようと、長い時間が、このラインが引き起こすことを明らかにしました問題:

$results  = $query->result_array(); 

CodeIgniterのではなく、このコマンドを使用して、あるオブジェクトとして結果を得るための別の方法提供しています:ご想像のとおり

$results  = $query->result(); 

を、私はすべてのCPUを食べPHPと同じ結果を取得していますし、 HTTP/1.1 504

  • とnginxの接続タイムアウト私は何も見つからなかった、Mysql_Slow_Queriesを記録しようとしています。
  • 表は

PHP CPU Usage on CodeIgniter Query

は私はあなたが何を聞かせてくださいInnoDBストレージエンジン(キーバッファ使用〜98%)を使用している、と私は見ているべきであるまたは多分私が探している必要があり、まさにどこために。私はこれがCodeIgniterのバグですが、プロトコールに従えば、私がする前に第二の意見が必要だと叫ぶのが大好きです。事前に

おかげ

+0

'$ this-> output-> enable_profiler(true)'を使用していますか? – Dan

+0

いいえ、私はそうではありません。私は、アプリケーションで使用されているコードを正確に提供しています。必要に応じて、なぜそのような問題を引き起こすプロファイラがないクエリがあるのか​​をご記入ください。ありがとうございます –

+1

クエリ 'SELECT id、content、created、FROM通知LIMIT 10 'を使用して問題があるかどうか確認できますか?そうでない場合は、フィルタリングの順序が問題になる可能性があります。 'SELECT id、content、作成された、FROM通知のORDER BY作成されたDESC LIMIT 10 'を試してください。それがよさそうだとすれば、注文は良いです。フィルタリングが問題になる可能性があります。 'SELECT id、content、created、見たFROM通知where receiver_id = 1 ORDER BY created DESC LIMIT 10'を試してください。それでも問題がなければ、 '$ UserID = sprintf("%d "、$ UserID);' '$ sql ... 'の前に実行して、UserIDをintに変換してみてください。 – zedfoxus

答えて

0

回答

問題は全くのMySQL側ではなく、表示され、証拠が、私はちょうどミリ秒単位で私ができるの行の任意の金額を照会することができるということです。後

function LoadNotifications($UserID)結果を返すと、CodeIgniterのは、実際に$results配列が返され、レンダリングしている間、私はこのようなJavaScriptのラインだった:問題は私の使用インラインJavascriptを難読化ライブラリCI_Minifierによって引き起こされた

foreach($results as $notification) 
{ 
    echo $notification["content"] . "<br />"; 
    echo "<script> some JS code </script>"; 
} 

をどの100回の難読化インスタンスが同時に起動され、ループ内にあった100本の<script>行を難読化しました。

ボトムライン:

あなたがたとえば、あなたのコードを難読化することができますまたはサードパーティ製のソフトウェアにそれを渡すことをどのようなタイプのインラインPHP DOM-解析を使用している場合、あなたははが含まれていないことを確認してください結果やレンダリングコードを返すときに見えるようにします。

あなたが持っている配列の出力を生成し、そのループから抜け出し、難読化のための最終出力をパイプ処理したり、単一のインスタンスで行っている処理をパイプしたりする正しい方法があります。

ありがとうございます@zedfoxusと@ダン私の手伝ってあなたの試みです。

0

最初のクエリでは、createdにインデックスが必要です。おそらく、その列をVARCHARではなく数値データ型に変換する必要があります。

2番目のクエリでは、別のインデックスのコンポジットINDEX(receiver_id, created)が必要です。現在のINDEX(receiver_id)はあまり良くありません。私がお勧めするプレフィックスですので、あなたのものを削除することをお勧めします。

+0

データベースのパフォーマンスを向上させるためのご意見やご感想をお寄せいただきありがとうございますが、これは私の質問には絶対に関係しておらず、参加している問題を解決するものでもありません。 –

+0

"タイムアウト"と "すべてのCPUを食べる"という "パフォーマンス"のおかげでありがとう。 'result *'はデータベースが結果セット全体の収集を完了するのを待っています。 –

+0

本当に、以下の私の答えをご覧ください。私はJSを難読化してインラインで難読化し、その結果でインライン難読化モジュールの何百ものインスタンスを解雇しました。 '$ result'はどのようにマージしても0.01秒で返されますが、DBの問題ではありませんでした。ありがとうございます。 –