MySQL GROUP_CONCAT 清單只出一半:先查連線的長度上限

分類標籤明明有三筆,匯出後卻只剩「alpha,be」,連 beta 都少了一截。若查詢使用 GROUP_CONCAT(),先檢查輸出長度上限,不要立刻認定資料已遺失。這個函式把多列值串成一個字串,結果過長時可能被截斷。

網站的標籤清單、附件名稱或後台報表都可能遇到這種情況。下面用 MySQL 8.4 的三筆文字示例分清兩件事:來源查到幾列,以及最後串出的文字是否完整。示例只讀臨時組出的資料,不建立或修改資料表。

先查執行那筆查詢的連線

SELECT VERSION(),
       @@SESSION.group_concat_max_len,
       @@GLOBAL.group_concat_max_len;

MySQL 8.4 的 group_concat_max_len 預設值是 1024,但站點可能已調整。它限制的是位元組數,不是可容納幾個標籤或幾個中文字;分隔符號也占輸出長度。因此要讀實際設定,不能只按「大約幾個字」估算。

尤其要看 SESSION 值。管理工具開的一條連線,和網站程式使用的連線可能不同;在工具裡調好了,不表示網站的那筆查詢已採用相同設定。

用小上限重現:三列資料,結果卻只剩半個名稱

在獨立測試連線依序執行以下內容,先保存原設定,再暫時將這條連線的上限設成 8:

SET @saved_limit = @@SESSION.group_concat_max_len;
SET SESSION group_concat_max_len = 8;

SELECT COUNT(*) AS source_rows,
       GROUP_CONCAT(name ORDER BY id SEPARATOR ',') AS names
FROM (
  SELECT 1 AS id, 'alpha' AS name
  UNION ALL SELECT 2, 'beta'
  UNION ALL SELECT 3, 'gamma'
) AS sample;
SHOW WARNINGS;

這筆查詢的 source_rows 仍是 3,但 names 是 alpha,be;緊接著的警告會指出 GROUP_CONCAT 有內容被截斷,這個例子會出現代碼 1260。原資料沒有因為截斷而被刪除,只是串接結果不完整。

請在那筆 SELECT 後立即查看警告,別先執行一串其他查詢,才回頭找截斷原因。若你的客戶端自動執行額外查詢,也要確認看到的是哪一筆操作的警告。

提高本連線上限後,再核對完整結果

仍在同一條測試連線,把上限改成足夠容納這個例子的 64,重跑相同的 SELECT:

SET SESSION group_concat_max_len = 64;

SELECT COUNT(*) AS source_rows,
       GROUP_CONCAT(name ORDER BY id SEPARATOR ',') AS names
FROM (
  SELECT 1 AS id, 'alpha' AS name
  UNION ALL SELECT 2, 'beta'
  UNION ALL SELECT 3, 'gamma'
) AS sample;
SHOW WARNINGS;

SET SESSION group_concat_max_len = @saved_limit;

這次應得到 3 與 alpha,beta,gamma。這組 ASCII 文字連同兩個逗號共占 16 位元組,64 只為了讓示例容易重現,並不是正式站的建議通用值。測完要在同一連線還原原值;若中途換了連線,保存原值的使用者變數也不能沿用。

正式報表要同時檢查長度與資料規則

確認是截斷後,再按實際資料量估算所需上限。不要直接設成極大值:MySQL 文件提醒,過高設定可能影響效能,甚至耗盡記憶體;輸出的有效最大長度也受 max_allowed_packet 限制。

如果資料量會一直增加,匯出程式可考慮逐列讀取,而非把所有名稱塞進一個大字串。程式確實需要串接時,應在執行查詢的那條連線設定並讀回 SESSION 值。使用連線池時,依框架的連線初始化與重設方式處理,避免把測試設定留給下一個借用者。

最後也別把每種「少了項目」都歸咎於長度:GROUP_CONCAT() 會略過 NULL,DISTINCT 會去掉重複值,JOIN 與 WHERE 則可能先改變來源列。範例把排序寫在 GROUP_CONCAT 內,是為了固定名稱串接順序;只在外層對查詢結果排序,不能替代這個順序要求。先核對來源,再看警告與最後字串,才知道應改查詢條件還是長度設定。

參考資料

原文鏈接:https://wntheme.com/mysql-group-concat-truncated-session-limit/,轉載請註明出處。
0
顯示驗證碼
沒有帳號?註冊  忘記密碼?