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 は設定ファイルを使います。

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲