1. MySQL查询全攻略:从基础模糊匹配到高级聚合分析
2023年MySQL全球使用率仍高达43.04%(DB-Engines最新数据),作为最流行的关系型数据库,查询操作占日常开发工作量的70%以上。今天我将结合8年DBA经验,详解MySQL中6大核心查询技术,包括实际业务中最易出错的模糊查询陷阱、正则表达式的高阶用法、聚合查询的性能优化等硬核内容。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础查询类型精讲
2.1 LIKE模糊查询的深度解析
LIKE查询是业务系统中最常用的模糊匹配方式,但90%的开发者都未完全掌握其精髓。基础语法看似简单:
sql复制SELECT * FROM products
WHERE name LIKE '%手机%';
这里需要特别注意:
- 前导通配符(
%手机)会导致索引失效,实测在100万数据量下查询耗时从5ms暴增至1200ms _表示单个字符匹配,如LIKE '张_'匹配"张三"但不匹配"张三四"- ESCAPE转义符处理特殊字符:
LIKE '%100%%' ESCAPE ''匹配包含"100%"的字符串
实战经验:对于中文模糊查询,建议使用
COLLATE utf8mb4_unicode_ci实现更智能的拼音匹配:sql复制SELECT * FROM users WHERE name LIKE '%zhang%' COLLATE utf8mb4_unicode_ci;
2.2 正则查询(REGEXP)的高阶应用
MySQL支持POSIX标准的正则表达式,比LIKE更强大但性能更低(约慢3-5倍)。典型场景:
sql复制-- 匹配手机号
SELECT * FROM customers
WHERE phone REGEXP '^1[3-9]\\d{9}$';
-- 提取JSON字段中的值
SELECT REGEXP_SUBSTR(log_data, '"ip":"([^"]+)"', 1, 1, '', 1)
FROM server_logs;
高级技巧:
REGEXP_INSTR()返回匹配位置REGEXP_REPLACE()实现复杂替换- 使用预编译正则模式提升性能
3. 特殊查询场景处理
3.1 空值查询的陷阱
NULL值处理是SQL中最易出错的部分之一:
sql复制-- 错误做法(不会返回NULL记录)
SELECT * FROM orders WHERE discount = NULL;
-- 正确做法
SELECT * FROM orders WHERE discount IS NULL;
联合查询时更需注意:
sql复制-- 使用<=>安全比较运算符
SELECT a.id, b.name
FROM table_a a LEFT JOIN table_b b
ON a.key <=> b.key;
3.2 BETWEEN和IN的优化之道
BETWEEN是范围查询的利器,但要注意:
- 包含边界值:
BETWEEN 10 AND 20等价于>=10 AND <=20 - 日期查询时推荐写法:
sql复制SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01 00:00:00' AND '2023-01-31 23:59:59';
IN查询在值较多时性能较差,替代方案:
- 使用临时表:
sql复制CREATE TEMPORARY TABLE temp_ids (id INT); INSERT INTO temp_ids VALUES (1),(2),(3); SELECT * FROM products WHERE id IN (SELECT id FROM temp_ids); - 使用JOIN:
sql复制SELECT p.* FROM products p JOIN temp_ids t ON p.id = t.id;
4. 聚合查询性能优化
4.1 五大聚合函数详解
| 函数 | 描述 | 优化建议 |
|---|---|---|
| COUNT() | 计数 | COUNT(*)最快,COUNT(col)会跳过NULL |
| SUM() | 求和 | 对DECIMAL类型注意精度问题 |
| AVG() | 平均值 | 先SUM再COUNT可减少浮点误差 |
| MAX()/MIN() | 最值 | 复合索引的最左列效果最佳 |
4.2 GROUP BY的进阶用法
sql复制-- WITH ROLLUP生成小计行
SELECT department, COUNT(*)
FROM employees
GROUP BY department WITH ROLLUP;
-- HAVING过滤分组
SELECT product_type, AVG(price)
FROM products
GROUP BY product_type
HAVING AVG(price) > 1000;
性能优化关键点:
- 使用
EXPLAIN确认是否用到索引 - 适当增加
tmp_table_size参数 - 考虑使用
SQL_BIG_RESULT提示
5. 综合查询实战案例
5.1 电商平台商品搜索
sql复制SELECT
p.id,
p.name,
p.price,
c.name AS category,
COUNT(r.id) AS review_count,
AVG(r.rating) AS avg_rating
FROM products p
JOIN categories c ON p.category_id = c.id
LEFT JOIN reviews r ON p.id = r.product_id
WHERE
(p.name LIKE '%智能%' OR p.description REGEXP '智能|AI')
AND p.price BETWEEN 1000 AND 5000
AND p.stock > 0
GROUP BY p.id
HAVING avg_rating >= 4.0
ORDER BY
CASE WHEN p.name LIKE '%旗舰%' THEN 0 ELSE 1 END,
p.sales DESC
LIMIT 20;
5.2 用户行为分析报表
sql复制SELECT
DATE(login_time) AS day,
COUNT(DISTINCT user_id) AS dau,
AVG(session_duration) AS avg_duration,
SUM(CASE WHEN device REGEXP 'iPhone|iPad' THEN 1 ELSE 0 END) AS ios_users,
SUM(CASE WHEN device LIKE '%Android%' THEN 1 ELSE 0 END) AS android_users
FROM user_sessions
WHERE
login_time BETWEEN '2023-06-01' AND '2023-06-30'
AND user_id IN (
SELECT id FROM users
WHERE register_time > '2023-01-01'
)
GROUP BY day
WITH ROLLUP;
6. 性能监控与优化
6.1 慢查询日志分析
在my.cnf中配置:
code复制slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
使用mysqldumpslow工具分析:
bash复制mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log
6.2 查询优化器提示
sql复制-- 强制使用索引
SELECT * FROM users FORCE INDEX(idx_email)
WHERE email LIKE 'user%@example.com';
-- 忽略索引
SELECT * FROM users IGNORE INDEX(primary)
WHERE id BETWEEN 1000 AND 2000;
7. 新型查询技术展望
MySQL 8.0+新增特性:
- 窗口函数:
RANK(),ROW_NUMBER()等 - 通用表表达式(CTE):
sql复制WITH regional_sales AS ( SELECT region, SUM(amount) AS total_sales FROM orders GROUP BY region ) SELECT * FROM regional_sales; - JSON路径查询:
JSON_EXTRACT(),->>运算符
我在实际工作中发现,合理组合这些查询技术可以解决90%以上的业务需求。特别是在处理千万级数据时,正确的查询方式能让执行时间从分钟级降到秒级。最近一个电商项目通过优化LIKE查询,使搜索接口响应时间从1.2s降至200ms,关键是把LIKE '%关键词%'改为全文索引查询。
