更多面试题请看这里: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[完成优化]