MySQL: 各データ グループからの最終エントリの抽出
頻繁なデータベース操作には、各データ グループ内の最新のレコードの取得が含まれます。 GROUP BY
はよく使用されますが、パフォーマンスの問題が発生する可能性があります。
次善のアプローチ
次のクエリは、サブクエリと降順を使用して、これを試みます。
<code class="language-sql">SELECT * FROM (SELECT * FROM messages ORDER BY id DESC) AS x GROUP BY name</code>
この方法は、より効率的な代替手段に関係なく、外部クエリがグループごとにテーブル全体をスキャンするため、非効率的です。
最適化されたソリューション (MySQL 8.0 )
MySQL 8.0 以降のバージョンでは、グループごとの操作を改善するためのウィンドウ関数が提供されています。 ROW_NUMBER()
は、各グループの最後のレコードを効率的に識別します:
<code class="language-sql">WITH ranked_messages AS ( SELECT m.*, ROW_NUMBER() OVER (PARTITION BY name ORDER BY id DESC) AS rn FROM messages AS m ) SELECT * FROM ranked_messages WHERE rn = 1;</code>
このクエリは、グループ内の各行をランク付けし、各行から最上位 (最後) のレコードのみを選択します。
代替 (MySQL 8.0 以前)
古い MySQL バージョン (8.0 より前) の場合は、次のアプローチが適しています。
<code class="language-sql">SELECT m1.* FROM messages m1 LEFT JOIN messages m2 ON (m1.name = m2.name AND m1.id < m2.id) WHERE m2.id IS NULL;</code>
これは、LEFT JOIN
を使用して、同じグループ内で上位の id
を持たない行を検索し、それぞれの最後のレコードを効果的に分離します。
パフォーマンスに関する考慮事項
最適なクエリは、データ サイズ、グループ分布、既存のインデックスに大きく依存します。 最も効率的なソリューションを選択するには、特定のシナリオのベンチマークを行うことが重要です。
以上がMySQLの各グループの最後のレコードを効率的に取得するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。