リスト取っても件数しか見ないならカウント検索

よくあるコード

こういうコードを時々見かけます。

public boolean hasMember(...) { // 会員データが存在するか?
    List<Member> memberList = selectList(...);
    return memberList.size() > 0;
}

指定された条件でMEMBERテーブルを検索して、一件以上あるかどうか?
を判定するメソッドの実装例ですが...

複数件の会員情報をDBサーバーからアプリサーバーに転送したけど、中身を全く見ていません。あるかないか?だけ。

もったいない!

ので、こうしたいですね。

public boolean hasMember(...) { // 会員データが存在するか?
    int memberCount = selectCount(...);
    return memberCount > 0;
}

メモリコストがもったいない

DBからデータを取得してアプリで扱うということは、そのデータの分だけアプリのメモリを利用していることになります。いまの時代の大容量メモリからしたら、大したことないと思われるかもしれませんが、このメソッド1分以内に何回呼ばれることでしょうか?

システムの性質にも寄るかもしれませんが、いまの時代のシステムはアクセス数も多く、データ量も膨大なものが多いです。1分以内で...何百?何千?何万?とチリも積もってメモリ使用量が膨れ上がってるかもしれません。

転送コストがもったいない

DBサーバーとアプリサーバーは、大抵は別サーバーです。

f:id:jflute:20210812163325p:plain

速いネットワークでつながれているとは思いますが、それでもネットワーク上を走っています。同じですね...1分以内で何百?何千?何万?とチリも積もって転送量が膨れ上がってるかもしれません。

ハードディスクがりがりもったいない

DBからデータを取るということは、基本的にハードディスクから引っこ抜いてきてると考えて良いです。もちろん、DBMS内でのキャッシュとか色々な工夫はありますが、すべてのデータではないでしょう。

ハードディスクから引くってのは基本的に遅いものです。

気付かずにもっさり動作

一箇所だけとかであれば体感できるほどのコストは生まれません。ですが、システムの中で何十箇所、何百箇所とこういったコードが散財していて、それでアクセス数で膨れ上がってるとしたら...

致命的に遅いわけじゃないけど画面のボタンを押すとなんか「うっ」って重い気がする、その原因の一つかもしれません。

フルスキャン検索で遅いとかならすぐ気づいて対処する方向に進みますが...

何年も掛けて少しずつ遅くなっていく

って気付かないんですよね。チリも積もればの方が怖いなって思ったりもします。

ちょっとの工夫でできるなら

もちろん、ある程度アプリはインフラ負荷を気にせず、開発効率やメンテナンス性を優先することもあります。

ただ、このケースはちょっとした意識だけで回避ができる話です。

DB検索は、遠い世界のハードディスクから持って来ている...

そう思っておいてちょうど良いくらいです。