管理杂谈OA答疑ERP答疑教程搜索

SQL查询优化30条军规:让数据库性能提升10倍


今天整理了30条SQL查询优化原则,每一条都是实战经验总结。用好它们,数据库性能提升立竿见影。

一、索引相关(1-2)

1. 查询优化第一步:在WHERE和ORDER BY涉及的列上建立索引

避免全表扫描,这是最基本也是最重要的原则。

2. 避免在WHERE子句中对字段进行NULL值判断

-- ❌ 会放弃索引SELECT id FROM t WHERE num IS NULL
-- ✅ 设置默认值0后这样查SELECT id FROM t WHERE num = 0

二、条件写法(3-5)

3. 避免使用 != 或 <> 操作符

这些操作符会导致引擎放弃使用索引。

4. 避免使用OR连接条件

-- ❌ 全表扫描SELECT id FROM t WHERE num = 10 OR num = 20
-- ✅ 用UNION ALL替代SELECT id FROM t WHERE num = 10UNION ALLSELECT id FROM t WHERE num = 20
5. IN和NOTIN要慎用
-- ❌ 全表扫描SELECT id FROM t WHERE num IN(1,2,3)
-- ✅ 连续值用BETWEENSELECT id FROM t WHERE num BETWEEN 1 AND 3

三、模糊查询(6)

6. 避免前缀模糊查询

-- ❌ 全表扫描SELECT id FROM t WHERE name LIKE '%abc%'
-- ✅ 考虑全文检索-- 或者改为前缀匹配SELECT id FROM t WHERE name LIKE 'abc%'

四、参数与表达式(7-10)

7. WHERE子句中使用参数会导致全表扫描

-- ❌ 编译时未知值,无法使用索引SELECT id FROM t WHERE num = @num
-- ✅ 强制使用索引SELECT id FROM t WITH(INDEX(索引名)) WHERE num = @num
8. 避免对字段进行表达式操作
-- ❌ 全表扫描SELECT id FROM t WHERE num/2 = 100
-- ✅ 改为对常量操作SELECT id FROM t WHERE num = 100 * 2
9. 避免对字段进行函数操作
-- ❌ 函数操作导致全表扫描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. 不要在“=”左边进行函数或运算

系统可能无法正确使用索引。

五、复合索引(11)

11. 复合索引必须使用第一个字段

字段顺序应与索引顺序一致,否则索引不会被使用。

六、查询写法(12-14)

12. 不要写无意义的查询

-- ❌ 消耗资源SELECT col1,col2 INTO #t FROM t WHERE 1=0
-- ✅ 直接建表CREATE TABLE #t(...)
13. 用EXISTS代替IN
-- ❌SELECT num FROM a WHERE num IN(SELECT num FROM b)
-- ✅SELECT num FROM a WHERE EXISTS(SELECT 1 FROM b WHERE num = a.num)

14. 索引不是万能的

当列有大量重复数据时(如性别字段),索引基本无效。

七、索引管理(15-16)

15. 索引不是越多越好

16. 避免频繁更新聚集索引列

聚集索引列改变会导致整个表物理顺序调整,消耗巨大资源。

八、字段设计(17-18)

17. 尽量使用数字型字段

数字比较一次完成,字符串需要逐个字符比较。

18. 用varchar/nvarchar代替char/nchar

变长字段存储空间小,查询效率更高。

九、SELECT写法(19)

**19. 不要用 SELECT ***

-- ❌ 返回不需要的字段SELECT * FROM t
-- ✅ 只取需要的字段SELECT id, name FROM t

十、临时表(20-24)

20. 优先使用表变量代替临时表

但注意表变量索引有限(只有主键)。

21. 避免频繁创建删除临时表

消耗系统表资源。

22. 临时表适用场景

23. 数据量大的情况用SELECT INTO

-- 大批量插入用SELECT INTO,减少日志SELECT * INTO #t FROM large_table
24. 用完临时表要显式删除
TRUNCATE TABLE #tDROP TABLE #t

十一、游标(25-27)

25. 尽量避免使用游标

游标效率差,超过1万行数据就应考虑改写。

26. 先找基于集的解决方案

集合操作通常比游标更有效。

27. 小型数据集可用FAST_FORWARD游标

必须引用多个表时才考虑使用。

十二、其他优化(28-30)

28. 存储过程设置SET NOCOUNT ON

CREATE PROC xxxASSET NOCOUNT ON-- 你的代码SET NOCOUNT OFF

减少客户端消息流量。

29. 避免大事务操作

大事务会锁定大量资源,影响并发能力。

30. 避免返回大数据量

数据量过大时,考虑分页或调整需求。

快速自查清单

问题
检查点
索引
WHERE/ORDER BY列是否有索引?
NULL
字段是否允许NULL?能否设默认值?
函数
WHERE条件左边是否有函数运算?
模糊查询
是否以%开头?
SELECT
是否用了*?
数据类型
能用数字不用字符,能用变长不用定长

总结

这30条原则核心就是一句话:让数据库能用上索引,减少全表扫描

阅读原文:原文链接


更多精彩文章浏览...
点击右上角图标分享到朋友圈
官方网站:http://www.clicksun.cn
咨询热线:400-186-1886
服务邮箱:service@clicksun.cn