[Mysql]複数のテーブルでマッチする値があるかのチェック

MySQL

タイトルで表現するにはいいニュアンスが見つからなかったのですが、やりたいことは以下になります。

カテゴリーマスタの項目に対して別のテーブルにデータが存在していれば『1 』を、存在していなければ1『0』でフラグを立てたい

データ

【カテゴリーマスタ:T1】

項目ID 項目名
1 バナナ
2 りんご
3 イチゴ
4 みかん

【データ:T2】

ユーザーID 項目ID
A0001 1
A0002 2
A0001 2
A0003 3
A0002 4
A0001 4

T2テーブルのユーザーA0001に紐づくカテゴリーを調べようとすると

結果は

項目ID 項目名
1 バナナ
2 りんご
4 みかん

これで「3のイチゴが選ばれてないんだな」と分かりますが、項目数が少ない場合はいいですが、項目数が多くなってくると何が選ばれていないのか分からなくなってしまいます。

こんな結果にしたいのです。

項目ID 項目名 結果フラグ
1 バナナ 1
2 りんご 1
3 イチゴ 0
4 みかん 1

きっかけは、Ajaxを使ってPHPで処理させた結果をページに表示するようにしていたのですが次第に時間が掛かるようになってきたのでSQLの方を改善しようと考えました。

状況としては、先にカテゴリーの項目をSELECTして、その結果をループでマッチングさせてデータの存在有無を返してたのですが、項目が増え、データが増えてくると時間が掛かるようになっている状況でした。
項目数に合わせてループさせてSQLを発行していたので、1項目あたりの結果が0.03秒で結果が返ってきていても90項目あれば3秒近く掛かってしまうという後を考えない作りになっていました。(ページが表示される応答速度)

SQLの変更

SQL文を改善しました。
CASEを使用してカテゴリーの項目IDにマッチするユーザーIDがあるかないかでフラグを立てます。

SQLを改善した結果のPHPの処理ですが、データ数は下記の条件で1人のユーザーに対する応答結果の比較です。
項目数:90件
データ数:16,000件

改善前:2.5秒前後
改善後:0.9秒前後

1秒程度ですが体感速度はかなり改善されました。

PHPなどを使ってループ処理をさせていると、1つのSQLあたりの処理時間が短い場合はスロークエリログにはでてこなくてボトルネックが隠れてしまうことがあります。
「あの処理入れて・・・」「この処理追加して・・・」とやっていて、SQLの結果を元にループ処理を重ねた結果で重くなっている可能性も高いので一旦組み上げ終って正常動作を確認できたらループ処理部分を見直すのは大事だなと。。。