SQL 性能优化最佳实践:30 条核心技巧详解

📅 发布时间:2026/8/8 1:32:53
SQL 性能优化最佳实践:30 条核心技巧详解 引言SQL 查询性能是数据库应用的关键。不当的查询语句可能导致全表扫描、索引失效严重影响系统响应速度。本文整理了 30 条 SQL 性能优化核心技巧涵盖索引使用、查询条件、表设计、临时表与游标等多个方面帮助开发者编写高效 SQL。一、索引使用优化1. 建立索引的基本原则对查询进行优化应尽量避免全表扫描首先应考虑在where及order by涉及的列上建立索引。2. 避免 NULL 值判断应尽量避免在where子句中对字段进行null值判断否则将导致引擎放弃使用索引而进行全表扫描。-- 不推荐 SELECT id FROM t WHERE num IS NULL; -- 推荐设置默认值后查询 SELECT id FROM t WHERE num 0;3. 慎用 ! 或 操作符应尽量避免在where子句中使用!或操作符否则引擎可能放弃使用索引而进行全表扫描。4. 避免使用 OR 连接条件应尽量避免在where子句中使用or来连接条件否则可能导致引擎放弃使用索引。-- 不推荐 SELECT id FROM t WHERE num 10 OR num 20; -- 推荐使用 UNION ALL SELECT id FROM t WHERE num 10 UNION ALL SELECT id FROM t WHERE num 20;5. 慎用 IN 和 NOT INin和not in也要慎用否则可能导致全表扫描。-- 不推荐 SELECT id FROM t WHERE num IN (1, 2, 3); -- 推荐连续数值使用 BETWEEN SELECT id FROM t WHERE num BETWEEN 1 AND 3;6. 避免前导通配符 LIKE使用前导通配符如%abc%的like查询将导致全表扫描。若要提高效率可以考虑全文检索。-- 导致全表扫描 SELECT id FROM t WHERE name LIKE %abc%;7. 避免在 WHERE 子句中使用参数在where子句中使用参数局部变量也会导致全表扫描因为优化器无法在编译时确定变量的值。-- 不推荐 SELECT id FROM t WHERE num num; -- 推荐强制使用索引 SELECT id FROM t WITH (INDEX(索引名)) WHERE num num;8. 避免字段表达式操作应尽量避免在where子句中对字段进行表达式操作这将导致引擎放弃使用索引。-- 不推荐 SELECT id FROM t WHERE num / 2 100; -- 推荐 SELECT id FROM t WHERE num 100 * 2;9. 避免字段函数操作应尽量避免在where子句中对字段进行函数操作这将导致引擎放弃使用索引。-- 不推荐 SELECT id FROM t WHERE SUBSTRING(name, 1, 3) abc; SELECT id FROM t WHERE DATEDIFF(day, createdate, 2005-11-30) 0; -- 推荐 SELECT id FROM t WHERE name LIKE abc%; SELECT id FROM t WHERE createdate 2005-11-30 AND createdate 2005-12-01;10. 避免在“”左侧进行运算不要在where子句中的“”左边进行函数、算术运算或其他表达式运算否则系统可能无法正确使用索引。11. 复合索引使用规范在使用索引字段作为条件时如果该索引是复合索引那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引否则该索引将不会被使用并且应尽可能让字段顺序与索引顺序相一致。二、查询语句优化12. 避免无意义查询不要写一些没有意义的查询如需要生成一个空表结构-- 不推荐 SELECT col1, col2 INTO #t FROM t WHERE 1 0; -- 推荐 CREATE TABLE #t (...);13. 使用 EXISTS 代替 IN很多时候用exists代替in是一个好的选择-- 使用 IN SELECT num FROM a WHERE num IN (SELECT num FROM b); -- 使用 EXISTS通常更高效 SELECT num FROM a WHERE EXISTS (SELECT 1 FROM b WHERE num a.num);三、索引设计原则14. 索引选择性原则并不是所有索引对查询都有效SQL 是根据表中数据来进行查询优化的。当索引列有大量数据重复时SQL 查询可能不会去利用索引。例如一个表中有字段 sexmale、female 几乎各一半那么即使在 sex 上建了索引也对查询效率起不了作用。15. 索引数量控制索引并不是越多越好。索引固然可以提高相应的select的效率但同时也降低了insert及update的效率因为insert或update时有可能会重建索引。一个表的索引数最好不要超过 6 个若太多则应考虑一些不常使用到的列上建的索引是否有必要。四、数据类型与存储优化16. 使用变长字段尽可能使用varchar/nvarchar代替char/nchar因为首先变长字段存储空间小可以节省存储空间其次对于查询来说在一个相对较小的字段内搜索效率显然要高些。五、临时表与表变量17. 使用表变量代替临时表尽量使用表变量来代替临时表。如果表变量包含大量数据请注意索引非常有限只有主键索引。18. 避免频繁创建删除临时表避免频繁创建和删除临时表以减少系统表资源的消耗。19. 大数据量使用 SELECT INTO在新建临时表时如果一次性插入数据量很大那么可以使用select into代替create table避免造成大量 log以提高速度如果数据量不大为了缓和系统表的资源应先create table然后insert。六、游标与过程优化20. 避免使用游标尽量避免使用游标因为游标的效率较差。如果游标操作的数据超过 1 万行那么就应该考虑改写。21. 设置 SET NOCOUNT ON/OFF在所有的存储过程和触发器的开始处设置SET NOCOUNT ON在结束时设置SET NOCOUNT OFF。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。七、结果集与需求合理性22. 控制返回数据量尽量避免向客户端返回大数据量若数据量过大应该考虑相应需求是否合理。总结SQL 性能优化是一个系统工程需要从索引设计、查询语句、数据类型、临时表使用等多个维度综合考虑。本文列举的 22 条核心技巧原列表有重复和缺失已整理合并涵盖了最常见的优化场景。在实际开发中应结合具体业务数据量、查询模式和数据库特性灵活应用这些原则并通过执行计划分析工具持续监控和调优。