PHP は PHP.ini ファイルでグローバルにメモリ制限を設定します。また、ローカルレベルで設定できることも知っています。
クエリメモリの制限は132MBに設定されていますが、次のエラーが発生し続けます。
Fatal error: Allowed memory size of 161480704 bytes exhausted (tried to allocate 32 bytes) in #{removed_file_path}/script.php on line #{line}
現在、ユーザーがページを閲覧して使用するときにエラーをキャッシュするエラーログファイルを介してシステムを監視していますが、cron
これらのファイルはどこにも記録されません。
mysql_query
への呼び出しを変更するとエラーを解決できますが、mysql_unbuffered_query
サーバー上のすべてのファイルを変更する場所を知る必要があります。スクリプトに実際にメモリの問題がない場合は、サーバーが可能であれば結果をRAMに読み込みたいので、コードを変更したくありません。
私たちのホストがそうしないように助言したので、私たちはPHPのメモリ制限を増やしたくありません。
メモリの問題を解決するにはどうすればよいですか? CentOS 6.7で動作しています。
答え1
あなたのPHPインタプリタは、132MB以上のメモリを必要とするすべてのスクリプトを終了するように設定されています。スクリプトが161MB以上のメモリを割り当てようとしています。問題は簡単で、解決策も簡単です。あなたはできます:
- PHPインタプリタにもっと割り当てるようにしてください。ホストがこれを推奨しない理由は、ホストがそうしないとデータベースが大きくなり続けるため、最終的に8 GB以上のメモリが割り当てられるためです。
- PHPと廃止された
mysql_*
APIを忘れて、そのようなメモリ制限を適用しないものを使用してください。通訳者があなたをいじめるのを止めても、オペレーティングシステムがある時点でおそらくあなたをいじめることに注意してください。 - スクリプトを改善してください。
mysql_unbuffered_query
解決策#3と一致する方法を使用してください。 PHPはもはやMySQLの結果セットをバッファリングしないので、もはや多くのメモリを占有せず、インタプリタももはや文句を言いません。デフォルトでは切り替え中です。バッファリングされたクエリからバッファリングされていないクエリへ(例#2と#3を参照、PDOへの移行を検討している時点は2016年です。)。PHPを使い続けてデザインが正しいと思うなら、これは解決策です。
可能であれば、サーバーは結果をRAMに読み込みたいので、コードを変更したくありません。
DBMSに従事している人は一般的にうまくいきます。クエリが必要以上に時間をかけないようにエンジンが最適化されています。あなたがPHPと古いmysql_*
APIを使用していることを考えると、速度が実際に問題になるとは思いません。 私の推測は、RAMではなくデータベースにデータを保持できることです。バッファリングされていないクエリを使用し、一度に1行ずつインポートまたは処理し、DBMSにさらに依存します(さらに、いくつかのバッファリングも実行できます...)。
それでも確信がない場合は、クエリ自体をもう一度考えてみることが改善される可能性があります。必要以上に多くのデータを取得できませんか?SELECT *
(私の言葉は、クエリの先頭に本当に必要ですか?)MySQLはあなたのために何かを処理できないと確信していますか? DBMSは非常に強力なツールなので、PHPスクリプトですべての作業を実行するのではなく、DBMSを使用して作業できます。典型的な例は、平均を計算することです。列のすべての数を取得し、合計ループを使用するのではなく、AVG(column)
ただ尋ねます。
あなたのスクリプトがなければ、この部分について追加のアドバイスを提供することは困難です(スタックオーバーフローの従業員はより良い仕事をすることができます)。しかし、この時点でスクリプトを十分に修正したと思われる場合は...次に送信してください。コードレビュー?これ以上改善する方法が見つからない場合は、誰かがそうする可能性が高くなります。
ある時点でPHPとMySQLが提供するすべてのオプションを使い果たしたと感じた場合は、他のものを使用することを検討する必要があります。実行しているデータ処理の種類に応じて、現在の作業に適した他のツールを見つけることができます。