2026年9月2日
2026年9月2日
MySQLのgroup_concat_max_lenを増やす方法|GROUP_CONCATが1024バイトで切れる原因
GROUP_CONCAT() で複数行の値を1つの文字列にまとめたとき、結果が途中で切れてしまうことがあります。原因は、結果の長さの上限を決める group_concat_max_len で、MySQL の既定値は 1024 バイトです。
この記事では、2026年10月時点の MySQL 8.4 と MariaDB 11.8(どちらも Docker の公式イメージ)で実際に試した結果をもとに、切れているかの確認方法と、上限を上げる4つの方法を説明します。
切れているかを確かめる
現在の値を見る
SELECT @@SESSION.group_concat_max_len, @@GLOBAL.group_concat_max_len;
| 製品 | 既定値 |
|---|---|
| MySQL 8.0 / 8.4 | 1024 |
| MariaDB 11 | 1048576(1MB) |
MariaDB は既定値が大きいので、同じクエリでも MySQL でだけ切れる、ということが起こります。
警告を見る
結果が切れたときは警告が出ます。クエリの直後に SHOW WARNINGS; を実行すると確認できます。
SELECT GROUP_CONCAT(name) FROM tags WHERE post_id = 1;
SHOW WARNINGS;
-- Warning | 1260 | Row 114 was cut by GROUP_CONCAT()
phpMyAdmin やアプリケーションからは警告が見えにくいので、結果の長さを LENGTH() で確かめるのも有効です。ちょうど 1024 前後で止まっていれば、上限で切れています。
上限は「文字数」ではなく「バイト数」
group_concat_max_len はバイト数です。utf8mb4 の日本語は1文字3バイトなので、日本語のタグ名を連結すると、1024 文字よりずっと手前で切れます。
SELECT LENGTH(GROUP_CONCAT(name)) AS bytes,
CHAR_LENGTH(GROUP_CONCAT(name)) AS chars
FROM tags;
-- bytes: 1022 / chars: 570(「タグ1」「タグ2」… を 600 件連結した例)
文字の途中で切れることはなく、上限に収まる最後の文字までが返ります。
上限を上げる4つの方法
必要な長さに合わせて、影響範囲の小さい方法から選びます。
| 方法 | 効く範囲 | 再起動後 | 必要な権限 |
|---|---|---|---|
SET SESSION |
その接続だけ | 消える | 不要 |
SET GLOBAL |
実行後に新しく接続したもの | 消える | SYSTEM_VARIABLES_ADMIN(または SUPER) |
SET PERSIST(MySQL 8.0 以降) |
実行後に新しく接続したもの | 残る | 同上 |
| 設定ファイル | 再起動後のすべて | 残る | サーバーの管理者権限 |
1. SET SESSION(その接続だけ)
SET SESSION group_concat_max_len = 100000;
SELECT GROUP_CONCAT(name ORDER BY name SEPARATOR ',') FROM tags;
再起動も特別な権限もいらず、ほかの接続に影響しません。レンタルサーバーのようにサーバー全体の設定を変えられない環境でも使えます。まずはこの方法を検討してください。
2. SET GLOBAL(サーバー全体、再起動まで)
SET GLOBAL group_concat_max_len = 100000;
すでに開いている接続(実行した自分の接続も含む)の値は変わりません。 新しく接続し直すと反映されます。また、MySQL を再起動すると元に戻ります。
3. SET PERSIST(MySQL 8.0 以降、再起動後も残す)
SET PERSIST group_concat_max_len = 100000;
SET GLOBAL と同じように反映され、さらにデータディレクトリの mysqld-auto.cnf に保存されるので、再起動後も残ります。元に戻すときは RESET PERSIST group_concat_max_len; で保存を消し、SET GLOBAL で値を戻します。MariaDB には SET PERSIST がないので、設定ファイルを使います。
4. 設定ファイル(再起動して反映)
[mysqld] セクションに追記し、MySQL を再起動します。
[mysqld]
group_concat_max_len = 100000
| 環境 | 設定ファイルの例 | 再起動 |
|---|---|---|
| Ubuntu / Debian の MySQL | /etc/mysql/mysql.conf.d/mysqld.cnf |
sudo systemctl restart mysql |
| RHEL 系の MySQL(公式リポジトリ) | /etc/my.cnf |
sudo systemctl restart mysqld |
| Debian / Ubuntu の MariaDB | /etc/mysql/mariadb.conf.d/50-server.cnf |
sudo systemctl restart mariadb |
再起動のあと、新しく接続して SELECT @@GLOBAL.group_concat_max_len; で反映を確認します。
WordPressの$wpdbで使う場合
WordPress はリクエストごとにデータベースへ接続するので、GROUP_CONCAT() を使うクエリの直前に、同じリクエストの中で SET SESSION を実行します。
<?php
global $wpdb;
// この接続(このリクエスト)だけ上限を 100,000 バイトに上げる
$wpdb->query( 'SET SESSION group_concat_max_len = 100000' );
$tags = $wpdb->get_var(
$wpdb->prepare(
"SELECT GROUP_CONCAT(t.name ORDER BY t.name SEPARATOR ', ')
FROM {$wpdb->terms} t
INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_id = t.term_id
WHERE tt.taxonomy = %s",
'post_tag'
)
);
サーバー全体の設定を変えずに済むので、ほかのサイトやプラグインに影響しません。結果の件数が多く上限を決めにくい場合は、GROUP_CONCAT() を使わずに $wpdb->get_col() で値を配列として受け取り、PHP の implode() でつなぐ方法もあります。
値の決め方と注意点
- 必要な最大長を見積もって決めます。 「連結する件数 × 1件の最大バイト数 + 区切り文字」が目安です。公式マニュアルは、値を大きくしすぎると性能の低下やメモリ不足(OOM)につながるおそれがあるとして、必要な長さを見積もって設定するよう求めています。
- 公式マニュアルでは、実際に返せる長さは
max_allowed_packetにも制約されるとされています。数十MBのような結果を前提にした設計は避けてください。 - 結果の型が変わります。
group_concat_max_lenが 512 以下なら結果はVARCHAR、それより大きいとTEXT(バイナリならBLOB)になります。 SET GLOBALと設定ファイルは、同じサーバーのほかのデータベースにも効きます。 共用のデータベースサーバーでは、SET SESSIONを優先してください。
まとめ
GROUP_CONCAT() が途中で切れるのは、MySQL の group_concat_max_len が既定で 1024 バイトだからです。SHOW WARNINGS の 1260 番の警告と LENGTH() で切れていることを確かめ、まずはそのクエリの直前に SET SESSION で必要な長さだけ上げます。サーバー全体で変えるなら、MySQL 8.0 以降は SET PERSIST、MariaDB は設定ファイルを使います。
関連記事: