これは私がいつも直面している問題です。幸いなことに、これを行うためのちょっとしたコツがあります。
SELECT
client_id,
SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY created DESC),",",1) AS `id`
FROM client_directory_data
WHERE verified = 1
GROUP BY client_id
また、行全体が必要な場合は、次のように参加できます。
SELECT
*
FROM (
SELECT
client_id,
SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY created DESC),",",1) AS `id`
FROM client_directory_data
WHERE verified = 1
GROUP BY client_id
) ids
JOIN client_directory_data USING (id);
もちろん、とにかくインデックス付きフィールドで注文する場合(したがって、とにかく効率的に結合できる)、MAX(id) AS id
実際にはパフォーマンスにほとんど影響を与えませんが、を使用することをお勧めします。MAX()を使用する主な理由は、実際にはコードを少し単純にするためです。また、フィールドにコンマが含まれている場合(グループの連結用に別の区切り文字を使用して回避できる)、またはGROUP_CONCATの最大長に達した場合(拡張可能でSET group_concat_max_len = xxx;
、とにかく警告のみが発生する)に発生する可能性のある落とし穴を回避します。
これがパフォーマンスの問題を抱えているように直感的に見える理由はわかりますが、実際には、特に大きなテーブルで、これらのクエリに対して私が見つけた最高のパフォーマンスの方法です。
これは、このスレッドの3つの方法を比較して、現在利用可能ないくつかの大きなテーブルから取得したベンチマークです。
クエリA:(〜5,000レコード、〜900結果、インデックスなしフィールド)
- GROUP_CONCATメソッド:0.0100秒
- MAXメソッド:0.102秒
- LEFT JOIN方式:0.0082秒
クエリB:(〜300,000レコード、〜95,000結果)
- GROUP_CONCATメソッド:1.8618秒
- MAXメソッド:1.7904秒
- LEFT JOINメソッド:6.4649秒
クエリC:(〜300,000レコード、〜7結果)
- GROUP_CONCATメソッド:0.103秒
- MAXメソッド:0.0102秒
- LEFTJOINメソッド:(4時間後に退屈しました)
クエリD:(〜500,000レコード、グループ化されるフィールドの〜5,000の異なる値)
- GROUP方式:0.1355秒
- MAXメソッド:0.0429秒
- LEFT JOINメソッド:(10分後に退屈しました)