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

MySQL UNION 聯合查詢實戰:全站搜索去重與性能優化

     編輯:MySQL 綜合教學

全站搜索是典型的多表聯合查詢場景:用戶在一個輸入框檢索關鍵詞,需同時命中文章、課程、產品等不同業務表。本文通過實際 SQL 拆解 UNION 與 UNION ALL 的語義差異、去重機制及性能取捨。

一、 業務場景與示例 SQL

SELECT * FROM (
  SELECT `id`,`subject` FROM `article` 
  WHERE `active`=1 AND `subject` LIKE '%調整圖片%' 
  ORDER BY `add_time` DESC
) AS t1
UNION ALL
SELECT * FROM (
  SELECT `id`,`class_name` AS `subject` FROM `web_class` 
  WHERE `active`=1 AND `class_name` LIKE '%調整圖片%' 
  ORDER BY `class_id` DESC
) AS t2
UNION
SELECT * FROM (
  SELECT `id`,`subject` FROM `article` 
  WHERE `active`=1 AND (`subject` LIKE '%調整%' OR `subject` LIKE '%圖片%') 
  ORDER BY `add_time` DESC
) AS t3;

二、 核心差異:UNION vs UNION ALL

特性UNION ALLUNION (DISTINCT)
語義直接合併所有結果集,保留重複行合併後做全局去重(排序+唯一)
性能O(N),無額外開銷O(N log N),需臨時表+排序/哈希去重
適用場景業務確定無重複、或允許重複、極度追求速度不同來源可能產生重複、需保證結果唯一

三、 示例 SQL 設計解析

  1. 前兩分支用 UNION ALL:article 與 web_class 為異構表,主鍵空間不重疊,業務邏輯上不可能重複,直接 ALL 避免去重開銷。
  2. 第三分支用 UNION:分詞查詢(%調整% OR %圖片%)結果集必然包含第一分支(%調整圖片%)的所有行,若用 ALL 會產生大量重複;改用 UNION 自動去重,保證最終結果集唯一。
  3. 字段對齊:各子查詢 SELECT 列數、順序、類型必須一致;第二分支用 AS subject 別名對齊第一、三分支的 subject。

四、 性能優化建議

  • 推倒到應用層合併:若結果集較大,考慮分批查詢後由應用層合併去重,減少數據庫臨時表壓力。
  • 加 LIMIT 保護:每個子查詢與最終結果均加 LIMIT N,防止全表掃描拖垮實例。
  • 全文索引替代 LIKE:高頻全站搜索建議引入 Elasticsearch 或 MySQL 5.7+ 內建 Fulltext Index,避免 %keyword% 導致全表掃描。
  • 覆蓋索引:子查詢只選取必要列,並建立 (active, subject, add_time) 聯合索引實現 Index Only Scan。

五、 總結

UNION ALL 是默認首選,除非業務確定需要去重。全站搜索架構演進路徑通常是:UNION → 應用層合併 → 專用搜索引擎。根據數據量與 QPS 選擇合適階段,切勿過度設計。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved