備忘録」カテゴリーアーカイブ

PHPとMySQL連携でメモリ不足

PHPを使ってMySQLの操作をしてるときに、データベースのレコード数が少ないときはいいんですが、ある一定以上のレコードを抽出するときにWWWサーバ側でメモリ不足のエラーが出ることがあります。

私の場合は、データベースから抽出したレコードを全て配列に格納してから処理をしているんですが、この配列変数で容量オーバーしてメモリ不足となることがありました。

対策としては、

1.抽出件数をLimitで制限して、whileなどで繰り返し処理を行う。

2.mysql_query→mysql_fetch_assocの流れではなく、mysql_unbuffered_query→mysql_fetch_assocという流れで処理をする。

1については、単純に一度に扱うデータ量を減らしています。

2のmysql_unbuffered_queryは、結構PHPのマニュアル本には載ってないことが多く私は知らなかった関数でした。

 

スタイルシートによる改ページ指定

PHPなどでWEBアプリを開発しているとどうしても印刷をきれいするという要望が出てきます。

TABLEの行数の制限などである程度は制御できるんですが、数ページに渡って印刷を行う場合はズレが生じてきます。

そこで、改ページ用のスタイルシートを埋め込むときれいにレイアウトされて印刷ができます。

例えば、改ページの区切り線にスタイルを設定する。

<hr style=”page-break-after: always;”>

 

表示される文字数によっては、変な位置でページが切れる場合があるんですがそこはページ内の文字数に余裕を持って構築しないといけないです。

PHPのスケジュール実行

とあるシステムでPHPを定時に実行しなくてはいけないことがありました。

最初はwindows系のサーバからだったので単純にタスクにURLを実行するように指示をして自動的にブラウザを起動、処理が完了したら自動的にブラウザを閉じるという設定をしてました。

ところが、サーバがLinux系の場合はどうするんだろう??

と悩んで調べてみるとまず[cron]を使ってどうにかするということが分かりました。しかし、何を呼び出せばいいのか。

そこで、わかったことは[wget]コマンドでURLを呼び出せばいいんだと。あとはシェルにダウンロードしたファイルを削除するように指示してあげれば定期的なPHPでの処理ができました。

 

 

MySQLチューニング

MySQLって軽快な動作をすると評判らしいのですが、チューニングをしてあげないと意味がないんですね。

最初はデフォルトの状態で運用していたのですが、レコード数が増えるにしたがって遅くなってしまう。そこで、いろいろと調べると設定ファイルを調整してあげれば格段に軽快な動作をするようになりました。

以下は私が設定した例です。

※設定はあくまで例です。参考程度にして下さい。

#スロークエリログ設定
log-slow-queries
long-query-time=30
log-long-format

#SELECT文をキャッシュ
query_cache_size=32M

#インデックスを用いないテーブル結合のときに使われるメモリ上の領域
join_buffer_size=8M
#インデックスを用いないテーブルスキャンのときに使われるメモリ上の領域
read_buffer_size=8M
#ソート後にレコードを読むときに使われるメモリ上の領域です。
#ディスクI/Oが減るのでORDER BYの性能向上が期待できます。
read_rnd_buffer_size=32M
#最大コネクション数
max_connections=50

#メモリに余裕がある場合に指定。検索に使われるインデックスをバッファに保存する際のメモリサイズ
key_buffer=32M
#入力データ保持のための最大バッファサイズ。画像など、大きなデータ挿入でこの制限に引っ掛かる可能性がある
max_allowed_packet=1M
#頻繁なアクセスに対し、データのキャッシュでディスクのI/O負荷を減らす場合に使用
table_cache=256
#頻繁なアクセスに対し、データのキャッシュでディスクのI/O負荷を減らす場合に使用
sort_buffer_size=16M
#値を大きくすることでインデックスを含まないクエリーの実行速度を上げる
record_buffer=1M

# スレッドの作成,削除は負荷が大きい.
# Threads_Createdの動きを見ながら変更.
thread_cache=16

# You can write your other MySQL server options here
#                                  Datafile(s) must be able to
#                                  hold your data and indexes.
#                                  Make sure you have enough
#                                  free disk space.
innodb_data_file_path = ibdata1:100M:autoextend:max:10000M
# InnoDBはOSキャッシュを使用しないため,全メモリの70-80%を当てると良い.
innodb_buffer_pool_size =128M
#InnoDBの内部データなどを保持するための領域
innodb_additional_mem_pool_size=10M

 

その他に「ここも設定したほうがいい」という項目があったら教えてください。