一、索引优化类技巧(1-8)
-
复合索引顺序设计
遵循”最左前缀原则”,将高选择性列放前。例如用户查询场景中,(user_id, order_date)的组合索引比(order_date, user_id)更高效,因为前者能快速过滤90%的数据。 -
覆盖索引应用
通过SELECT字段全部包含在索引中避免回表。如电商订单查询:CREATE INDEX idx_order_cover ON orders(order_id, user_id, amount)INCLUDE (status, create_time); -- 伪代码示例SELECT order_id, amount FROM orders WHERE user_id=1001;
-
索引下推优化
MySQL 5.6+支持的Index Condition Pushdown技术,将WHERE条件过滤下推到存储引擎层。测试显示复杂条件查询性能提升可达40%。 -
索引选择性计算
通过SELECT COUNT(DISTINCT col)/COUNT(*) FROM table计算列选择性,选择性>30%的列适合建索引。用户ID等唯一标识列选择性通常达99%。 -
函数索引使用
对处理后的列建立函数索引,如:-- PostgreSQL语法示例CREATE INDEX idx_upper_name ON users(UPPER(name));SELECT * FROM users WHERE UPPER(name)='JOHN';
-
部分索引优化
仅对满足条件的记录建索引:-- PostgreSQL语法示例CREATE INDEX idx_active_users ON users(email) WHERE status='active';
-
索引合并策略
MySQL的index_merge优化可合并多个单列索引。通过EXPLAIN查看是否使用union或intersect访问类型。 -
索引维护成本
定期分析ANALYZE TABLE更新统计信息,避免因数据分布变化导致索引失效。建议每周执行一次统计信息更新。
二、查询重构类技巧(9-16)
-
OR条件优化
将WHERE a=1 OR a=2改写为WHERE a IN (1,2),执行计划更优。测试显示复杂OR查询响应时间缩短65%。 -
EXISTS替代JOIN
关联子查询场景下,EXISTS在找到匹配后立即返回:SELECT u.name FROM users uWHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id=u.id AND o.amount>1000);
-
LIMIT分页优化
深度分页时使用延迟关联:
```sql
— 传统方式(性能差)
SELECT * FROM orders ORDER BY create_time LIMIT 100000, 20;
— 优化方式
SELECT o.* FROM orders o
JOIN (SELECT id FROM orders ORDER BY create_time LIMIT 100000, 20) tmp
ON o.id=tmp.id;
12. **CTE递归查询**处理层级数据时使用WITH RECURSIVE:```sqlWITH RECURSIVE dept_tree AS (SELECT * FROM departments WHERE id=1UNION ALLSELECT d.* FROM departments dJOIN dept_tree dt ON d.parent_id=dt.id) SELECT * FROM dept_tree;
-
窗口函数应用
计算排名、移动平均等场景:SELECT user_id, amount,RANK() OVER(PARTITION BY user_id ORDER BY amount DESC) as rankFROM orders;
-
JSON数据查询
现代数据库支持JSON路径查询:-- MySQL 5.7+语法SELECT user_id, JSON_EXTRACT(profile, '$.address.city') as cityFROM users;
-
通用表表达式(CTE)
提高复杂查询可读性:WITH user_stats AS (SELECT user_id, COUNT(*) as order_countFROM orders GROUP BY user_id)SELECT u.name, s.order_countFROM users u JOIN user_stats s ON u.id=s.user_id;
-
批量操作优化
使用批量INSERT替代单条插入:INSERT INTO orders (user_id, amount) VALUES(1001, 200), (1002, 350), (1003, 180);
三、执行计划分析类技巧(17-22)
-
EXPLAIN深度解读
重点关注type列(ALL/index/range/ref/eq_ref/const)、key列(实际使用索引)、Extra列(Using filesort/Using temporary)。 -
强制索引使用
通过索引提示强制使用特定索引:SELECT * FROM orders FORCE INDEX(idx_user_date)WHERE user_id=1001 AND create_time>'2023-01-01';
-
慢查询日志分析
配置long_query_time=1s捕获慢查询,使用pt-query-digest等工具分析。某电商案例显示,优化前10的慢查询占总耗时的78%。 -
性能模式监控
启用数据库性能模式,收集等待事件、IO统计等指标。MySQL的Performance Schema提供200+监控维度。 -
直方图统计优化
MySQL 8.0+支持创建列数据分布直方图:ANALYZE TABLE orders UPDATE HISTOGRAM ON amount;
-
执行计划缓存
合理设置query_cache_size(注意MySQL 8.0已移除查询缓存),考虑使用预处理语句。
四、高级特性应用类技巧(23-30)
-
分区表策略
按时间范围分区提升大表查询效率:CREATE TABLE logs (id BIGINT,log_time DATETIME,message TEXT) PARTITION BY RANGE (YEAR(log_time)) (PARTITION p2022 VALUES LESS THAN (2023),PARTITION p2023 VALUES LESS THAN (2024));
-
物化视图实现
通过定期刷新实现物化视图:
```sql
— 创建汇总表
CREATE TABLE order_stats AS
SELECT DATE(create_time) as day,
SUM(amount) as total_amount
FROM orders GROUP BY day;
— 每日刷新
INSERT INTO order_stats
SELECT DATE(create_time) as day,
SUM(amount) as total_amount
FROM orders
WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
GROUP BY day
ON DUPLICATE KEY UPDATE total_amount=VALUES(total_amount);
25. **并行查询优化**Oracle、SQL Server等数据库支持并行查询,通过`MAXDOP`参数控制并行度。测试显示大数据量聚合查询提速3-5倍。26. **临时表空间优化**复杂查询产生的临时表应使用独立表空间,避免与主表空间竞争IO资源。27. **数据库参数调优**关键参数配置示例:- `innodb_buffer_pool_size`:设为物理内存的50-70%- `sort_buffer_size`:复杂排序时设为2-8MB- `join_buffer_size`:大表连接时设为1-4MB28. **分布式SQL优化**分库分表场景下使用全局表、分片键优化。某金融系统案例显示,合理分片使跨库JOIN性能提升60%。29. **SQL注入防护**使用参数化查询替代字符串拼接:```java// Java JDBC示例PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username=? AND password=?");stmt.setString(1, username);stmt.setString(2, password);
- AI辅助优化
部分数据库管理工具已集成AI优化建议,如百度智能云的数据库智能管家可自动识别低效SQL并提供优化方案。
五、最佳实践总结
- 三步优化法:先定位问题SQL→分析执行计划→针对性优化
- 基准测试原则:修改前后的SQL应在相同数据量、硬件环境下测试
- 渐进优化策略:从索引优化开始,逐步尝试查询重构和架构调整
- 监控常态化:建立持续的性能监控体系,避免性能退化
实际案例显示,综合应用上述技巧可使复杂查询响应时间从秒级降至毫秒级,系统吞吐量提升3-10倍。建议开发者建立自己的SQL优化checklist,持续积累优化经验。