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

MySQL 條件查詢 WHERE 子句完整指南:比較運算子、邏輯組合、索引優化

     編輯:MySQL 綜合教學

WHERE 子句核心語法

SELECT `column_list`
FROM `table_name`
WHERE `condition_expression`;

比較運算子完整對照

運算子含義範例索引友善度
=等於status = 1✅ 最佳 (ref/const)
<> / !=不等於status <> 0⚠️ 範圍掃描
>大於age > 18✅ 範圍查詢
<小於price < 100✅ 範圍查詢
>=大於等於created_at >= '2024-01-01'✅ 範圍查詢
<=小於等於score <= 60✅ 範圍查詢
BETWEEN ... AND ...範圍包含邊界age BETWEEN 18 AND 60✅ 等價 >= AND <='
IN (...)列表匹配id IN (1,2,3)✅ 優化器轉為多個 =
NOT IN (...)不在列表status NOT IN (0,-1)⚠️ 子查詢慎用
LIKE 'pattern'模糊匹配name LIKE '張%'✅ 前綴可用索引
LIKE '%pattern%'包含匹配content LIKE '%關鍵字%'❌ 全表掃描
IS NULL為空deleted_at IS NULL✅ 可用索引
IS NOT NULL不為空email IS NOT NULL✅ 可用索引
REGEXP正則表達式phone REGEXP '^09\\d{8}$'❌ 全表掃描

邏輯運算子與優先級

-- 優先級:NOT > AND > OR
-- 明確分組請用括號
SELECT * FROM orders
WHERE (status = 1 OR status = 2)
  AND created_at >= '2024-01-01'
  AND user_id NOT IN (SELECT id FROM banned_users);

實戰範例:電商訂單篩選

-- 待出貨訂單:已付款、未出貨、非取消、近 30 天
SELECT `order_id`, `user_id`, `total_amount`, `created_at`
FROM `orders`
WHERE `payment_status` = 'paid'
  AND `shipping_status` = 'pending'
  AND `order_status` NOT IN ('cancelled', 'refunded')
  AND `created_at` >= DATE_SUB(NOW(), INTERVAL 30 DAY)
ORDER BY `created_at` ASC
LIMIT 50;

索引優化:讓 WHERE 走索引

WHERE 模式建議索引EXPLAIN type避坑提醒
col = ?INDEX idx_col (col)ref/const
col > ?INDEX idx_col (col)range
col1 = ? AND col2 = ?INDEX idx_c1_c2 (col1, col2)ref最左前綴:col1 必須在前
col1 = ? AND col2 > ?INDEX idx_c1_c2 (col1, col2)ref/rangecol1 等值、col2 範圍
col1 > ? AND col2 = ?INDEX idx_c2_c1 (col2, col1)ref/range等值欄位優先放前面
col LIKE 'prefix%'INDEX idx_col (col)range前綴查詢可用索引
col LIKE '%suffix'無法用索引ALL考慮全文索引或反轉欄位
func(col) = ?無法用索引ALL改用函數索引 (MySQL 8.0) 或冗余欄位

常見效能殺手

  1. 隱式轉換:WHERE varchar_col = 123 → 全表掃描。字串比字串、數值比數值
  2. 函數包裹欄位:WHERE DATE(created_at) = '2024-01-01' → 不走索引。改用 created_at >= '2024-01-01' AND created_at < '2024-01-02'
  3. OR 橫跨不同索引:WHERE idx_col1 = 1 OR idx_col2 = 2 → 可能全掃。用 UNION 分開查再合併
  4. NOT IN 子查詢:WHERE id NOT IN (SELECT ...) → 慢。改用 NOT EXISTS 或 LEFT JOIN ... WHERE IS NULL
  5. 字串前導通配符:LIKE '%keyword%' → 全掃。用全文索引或 Elasticsearch

MySQL 8.0 新功能:函數索引與隱形索引

-- 函數索引:直接為運算式建索引
ALTER TABLE `orders` ADD INDEX `idx_date_created` ((DATE(`created_at`)));
-- 現在 WHERE DATE(created_at) = '2024-01-01' 可走索引

-- 隱形索引:測試移除影響不實際刪除
ALTER TABLE `t` ALTER INDEX `idx_name` INVISIBLE;
-- 優化器忽略此索引,驗證效能後再決定 DROP

總結

MySQL WHERE 子句是查詢效能分水嶺。核心原則:等值優於範圍、最左前綴、避免函數包裹欄位、隱式轉換、OR 橫跨索引。善用 EXPLAIN 驗證 type=ref/range 而非 ALL。複雜條件用括號明確優先級,大量文字搜尋上全文索引或專業搜尋引擎。

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