首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 雙字段去重查詢優化:聯系人列表場景下的 CONCAT+CASE 技巧

     編輯:MySQL 綜合教學

業務場景

表 chat_history 記錄聊天歷史:

  • id:自增主鍵
  • from_uid:發送方 UID
  • to_uid:接收方 UID

需求:獲取某用戶(如 uid='xxx')的**最新聯系人列表**,按最後消息時間倒序,支援分頁。

初級方案:GROUP BY 雙字段 + 程序合併

SELECT MAX(id) AS mid, from_uid, to_uid
FROM chat_history
WHERE from_uid='xxx' OR to_uid='xxx'
GROUP BY from_uid, to_uid
ORDER BY mid DESC

缺陷:雙向通信產生兩行(A→B 與 B→A),需程序層合併,無法直接 LIMIT 分頁。

優化方案:構建統一標識欄位 + 單字段 GROUP BY

核心思路:將 (from_uid, to_uid) 無序對轉換為有序唯一標識。

SELECT 
  MAX(id) AS mid,
  from_uid,
  to_uid,
  CASE to_uid 
    WHEN 'xxx' THEN CONCAT(to_uid, from_uid) 
    ELSE CONCAT(from_uid, to_uid) 
  END AS to_from_uid
FROM chat_history
WHERE to_uid = 'xxx' OR from_uid = 'xxx'
GROUP BY to_from_uid
ORDER BY mid DESC
LIMIT 0, 20

關鍵技術點解析

  1. CASE WHEN 條件構造有序對:以目標 UID 為基準,確保 (A,B) 和 (B,A) 生成相同字符串
  2. CONCAT 字符串拼接:生成唯一標識 to_from_uid
  3. 單字段 GROUP BY:直接按構造標識分組,天然去重
  4. MAX(id) 保留最新記錄:自增 ID 代表時間順序
  5. 原生支援 LIMIT 分頁:無需中間表或程序二次處理

性能優勢

  • 單次掃描、單次排序、無臨時表
  • 可利用 (from_uid, to_uid) 聯合索引優化 WHERE 條件
  • 避免子查詢或衍生表的物化開銷
  • 擴展應用

    同類場景:

    • 好友關係表(雙向唯一)
    • 轉賬記錄雙向去重
    • 任意無序雙元組去重統計
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved