読者です 読者をやめる 読者になる 読者になる

mysqlからデータを取得してわざわざphpでソートする

php mysql

はじめに

僕はけっこうコレやります。
どういうときに使うか考えて見る

・レコードが多い複数のテーブルをjoinしなくてはならない場合
・テーブル分割していてそれぞれのテーブルからデータを取得してきて結果をマージしなくてはならない場合

などなど
テーブル設計上やらなくてはならない場合やjoinしたクエリのレスポンスが遅すぎる場合など


昔いた職場ではdbサーバは分割できるようにテーブル設計するように決めていた。
なので、一覧表示とかするときには必然的にこういう処理が必要になるので自分的には違和感ありませんでした


が、意味的に1テーブルですむところをわざわざ別テーブルに分けるっていう考え方は意外と受け入れられないことも多い?
と最近思います


まぁ、それやりたいならどうしてmysql使うの?とか言われたら「慣れてるから」・・・としか言えないのですが

問題点と工夫

たとえば画面に表示しなくてはならない項目がたくさんある場合で
mysqlからデータ取得してきてそれをphpでソートする場合を考える

全レコードを取得するのでデータ量が多いとメモリの消費も増える
で「Allowed memory size of xxx」が発生


データの件数や処理速度の要件にもよるけどphpでソートしても僕の場合はそこまで気にならないことが多いです
でも、このメモリオーバーのエラー出ると処理落ちしてしまうのでこれは対応しなくてはなりません

問題のコード
// dbから一覧表示する対象のレコードを取得
$allList = "select カラム1, カラム2, 〜, カラム500 from テーブル where 〜"の結果

// 取得したデータを他のデータとソートしたりマージしたり・・・

// 1ページに必要な部分を切り出す
$list = array_slice($allList, $from=0, $to=50);

// $listの内容を画面に表示
解決するコード
// dbから一覧表示する対象のレコードを取得
// ただしソートやマージに必要なカラムだけを取得
$allList = "select カラムA,カラムB from テーブル where 〜"の結果

// 取得したデータを他のデータとソートしたりマージしたり・・・

// 1ページに必要な部分を切り出す
$list = array_slice($allList, $from=0, $to=50);

// 画面表示に不足な情報を取得
// ※ここでは1件ずつ取得してるけどSQL一発で取得できればなおよいと思う
foreach ($list as $key => $value) {
    $list[$k] = "カラム1, カラム2, 〜, カラム500 from テーブル where プライマリキーとか "の取得結果
}

// $listの内容を画面に表示

地味な内容でしたが、以上です