SQL优化手段有哪些

更多面试题请看这里:https://interview.raoyunsoft.com/

以下是一些高效的SQL优化手段,能显著提升数据库查询性能:

1. 避免使用SELECT *

只查询必要字段,减少数据传输量和内存消耗:

sql 复制代码
-- 不推荐  
SELECT * FROM users;  

-- 推荐  
SELECT id, name, email FROM users;  

2. 用JOIN替代子查询

子查询易导致性能瓶颈,优先使用连接操作:

sql 复制代码
-- 不推荐  
SELECT * FROM orders 
WHERE user_id IN (SELECT id FROM users WHERE status=1);  

-- 推荐  
SELECT o.* FROM orders o  
INNER JOIN users u ON o.user_id = u.id  
WHERE u.status = 1;  

3. 谨慎处理IN/NOT IN

改用EXISTS或连接查询,避免全表扫描:

sql 复制代码
-- 不推荐  
SELECT * FROM products 
WHERE category_id NOT IN (SELECT id FROM categories);  

-- 推荐  
SELECT p.* FROM products p  
LEFT JOIN categories c ON p.category_id = c.id  
WHERE c.id IS NULL;  

4. 优化OR条件

UNION ALL重组查询(确保无重复数据时):

sql 复制代码
-- 不推荐  
SELECT * FROM logs 
WHERE type='error' OR type='warning';  

-- 推荐  
SELECT * FROM logs WHERE type='error'  
UNION ALL  
SELECT * FROM logs WHERE type='warning';  

5. 避免!=<>操作符

会导致索引失效,改用范围查询:

sql 复制代码
-- 不推荐  
SELECT * FROM orders WHERE status <> 'canceled';  

-- 推荐  
SELECT * FROM orders  
WHERE status < 'canceled' OR status > 'canceled';  

6. 处理NULL值的正确方式

为字段设置默认值 ,避免IS NULL判断:

sql 复制代码
-- 建表时设置默认值  
ALTER TABLE employees MODIFY bonus INT DEFAULT 0;  

-- 查询优化  
SELECT * FROM employees WHERE bonus = 0;  -- 替代IS NULL  

7. 索引优化技巧

  • 避免索引列参与计算

    sql 复制代码
    -- 索引失效  
    SELECT * FROM orders WHERE YEAR(create_time) = 2023;  
    
    -- 索引生效  
    SELECT * FROM orders  
    WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31';  
  • 复合索引遵循最左匹配原则

  • 覆盖索引减少回表查询

8. 分页查询优化

深分页时使用游标替代LIMIT offset

sql 复制代码
-- 低效(offset越大越慢)  
SELECT * FROM posts ORDER BY id LIMIT 10000, 20;  

-- 高效  
SELECT * FROM posts  
WHERE id > 10000 ORDER BY id LIMIT 20;  

9. 执行计划分析

使用EXPLAIN诊断查询性能:

sql 复制代码
EXPLAIN SELECT * FROM orders 
WHERE user_id = 100 AND amount > 500;  

关键指标关注:

  • type:扫描类型(目标:ref/range)
  • key:实际使用的索引
  • rows:预估扫描行数

10. 定期维护数据库

  • 重建碎片化索引OPTIMIZE TABLE table_name
  • 更新统计信息ANALYZE TABLE table_name
  • 清理历史数据:归档或分区存储
graph TD A[SQL查询] --> B{是否高效?} B -->|否| C[分析EXPLAIN] C --> D[确认索引使用] D --> E{索引是否生效?} E -->|否| F[优化查询条件] E -->|是| G[检查连接方式] G --> H[改用JOIN/EXISTS] H --> I[验证性能提升] I -->|不足| J[考虑分库分表] I -->|达标| K[完成优化]
相关推荐
像我这样帅的人丶你还10 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
ZzT11 小时前
公司用 AI 筛简历,他写了个 AI 帮你挑公司
面试·aigc·ai编程
PBitW11 小时前
GPT训练我的第四天,被打惨了!!!😭😭😭
前端·javascript·面试
plainGeekDev12 小时前
GreenDAO → Room
android·java·kotlin
jiayou6413 小时前
KingbaseES 表级与列级加密完全指南
数据库·后端
云技纵横16 小时前
@Transactional 到底要不要加 rollbackFor?一次数据不一致事故讲清楚
后端·面试
Moment16 小时前
牛逼,NextJs 从 16.3 开始全面拥抱 Agent Native 🥰🥰🥰
前端·后端·面试
胡萝卜术16 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
亦暖筑序17 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端
胡萝卜术17 小时前
从暴力到Z字形消元:力扣240「搜索二维矩阵II」的降维打击之路
前端·javascript·面试