メディアテーブルにcustom_properties
というMySQL JSONデータ型があるとします。
custom_properties
列に格納されているjsonデータの例は次のとおりです。
{
"company_id": 1,
"uploaded_by": "Name",
"document_type": "Policy",
"policy_signed_date": "04/04/2018"
}
私のPHP Laravelアプリでは、次のようにします:
$media = Media::where('custom_properties->company_id', Auth::user()->company_id)->orderBy('created_at', 'DESC')->get();
これにより、会社1に属するすべてのメディアアイテムがフェッチされます。
私の質問は、100万のメディアレコードがあるとしましょう。これは、パフォーマンスの観点からレコードをフェッチするための悪い方法でしょうか? MySQLがどのようにJSONデータ型にインデックスを付けるかについて誰かが光を当てることはできますか?
MySQL公式ドキュメント から:
JSON列に格納されたJSONドキュメントは、ドキュメント要素への迅速な読み取りアクセスを可能にする内部形式に変換されます。後でサーバーがこのバイナリ形式で保存されたJSON値を読み取る必要がある場合、値をテキスト表現から解析する必要はありません。バイナリ形式は、サーバーがドキュメント内の前後のすべての値を読み取ることなく、キーまたは配列インデックスによってサブオブジェクトまたはネストされた値を直接検索できるように構造化されています。
通常のカラムを使用するよりもパフォーマンスが低下することは間違いないと思います。
JSON属性にインデックスを付ける方法は、必要な特定の属性(company_id)の仮想生成列を作成し、仮想列にインデックスを付け、その列を使用してクエリをフィルター処理することです。