SqlServer优化方案

本文介绍了数据库查询优化的多种方法,包括通用优化,如使用参数化查询、避免select *等;字段类型、where条件、索引、分页语句、事务、临时表和游标等方面的优化。通过这些优化可提高查询效率、减少资源消耗和提升系统并发能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通用平常优化:
1. 使用参数化查询:防止SQL注入,预编译SQL命令提高效率
2. 去掉不必要的查询和搜索字段:其实在项目的实际应用中,很多查询条件是可有可无的,能从源头上避免的多余功能尽量砍掉,这是最简单粗暴的解决方案。
3. 选择最有效率的表名顺序: 数据库的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表放在最后,如果有3个以上的表连接查询,那就需要选择那个被其他表所引用的表放在最后。
4. 不要使用select *:不要使用select *,以提高查询效率,减少输出的数据量,提高传输速度(数据库或在解析过程中将"*"依次转换成所有列名,这意味着消耗更多的时间)
5. 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
6. 减少访问数据库的次数:通过存储过程等,把多条语句放在一个存储过程中执行,减少数据库访问次数
7. 整合简单的、无关联的数据库访问:如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系))
8. 删除重复记录:删除重复记录,减少数据库文件大小
9. 使用表的别名(Alias):当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误.
10. 使用列的别名:当列的名称很长的时候,使用简短的列的别名可以查询结果更清晰,更简洁。
11. 用EXISTS替代IN、用NOT EXISTS替代NOT IN:无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历). 为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS.
12. 统计相关的查询,影响结果集往往巨大,应避免在业务高峰期执行统计相关的查询,或者仅在从库中执行统计查询。同时建议把数据先保存在内存、缓存中(如redis),再按一定策略写入数据库。
13. select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的,可以用其他方法代替。
14. 使用truncate代替delete清空整个数据表:当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. (可以恢复到执行删除命令之前的状态) 而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短.

字段类型优化:
1. 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连 接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
2. 最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库.(备注、描述、评论之类的可以设置为 NULL)

where条件语句优化:
1. WHERE子句中的连接顺序:数据库采用自右而左的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前(左), 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾(右).
2. 避免在where语句中出现字段的类型转换(字段的类型和传入的参数类型不一致的时候发生的隐式类型转换)
3. 不要在where条件语句中的"="左边进行函数、算数运算或其他表达式运算,可以通过使用冗余字段来替代函数运算,否则系统无法正确使用索引
4. where 子句中对字段进行 null 值判断、包含not、!=、<>等操作符,或like的关键词前加%(like '%关键词'),都无法使用索引,从而引发全表扫描.
5. 使用like进行模糊查询时应注意,除非必要,否则不要在关键词前加%,否则必然导致全表查询

索引优化:
1. 索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
2. 用索引提高效率:合理使用索引和复合索引同样能提高效率.但使用索引是有代价的, 索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改. 这意味着每条记录的INSERT , DELETE , UPDATE将为此多付出4 , 5 次的磁盘I/O . 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢.。定期的重构索引是有必要的。
3. 在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用。
4. 要注意索引的维护,周期性重建索引,重新编译存储过程。

分页语句优化:
1. 分页查询的优化。页数比较多的情况下,如limit 10000,10 影响的结果集是10010行,查询速度会比较慢。推荐的解决方案是:先只查询主键select id from table where .. order by .. limit 10000,10(搜索条件和排序请建立索引),再通过主键去获取数据。
2. 对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差。

事务的优化:
1. 尽量使用COMMIT:尽可能在程序中使用commit,这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少,commit每个数据库引擎都不同,sqlserver默认一条sql语句就是一个事务。
2. 尽量避免大事务操作,提高系统并发能力。
3. 只在必要的情况下才使用begin tran:begin tran保证了数据的一致性,可以确保要么几个表都修改成功,要么都不成功,但Begin tran付出的代价是在提交之前,所有SQL语句锁住的资源都不能释放,直到commit掉。Begin tran使用的原则是,在保证数据一致性的前提下,begin tran 套住的SQL语句越少越好!有些情况下可以采用触发器同步数据,不一定要用begin tran。

临时表优化:
1. 避免频繁创建和删除临时表,以减少系统表资源的消耗。
2. 使用“临时表”暂存中间结果:将临时结果暂存在临时表,后面的查询就在tempdb中了,这可以避免程序中多次扫描主表,也大大减少了程序执行中“共享锁”阻塞“更新锁”,减少了阻塞,提高了并发性能。同时也能简化sql语句的复杂度。
3. 在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
4. 如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
5. 如果临时表的数据量较大,需要建立索引,那么应该将创建临时表和建立索引的过程放在单独一个子存储过程中,这样才能保证系统能够很好的使用到该临时表的索引。
6. 尽量避免使用distinct、order by、group by、having、join、cumpute,因为这些语句会加重tempdb的负担。
7. 慎用大的临时表与其他大表的连接查询和修改,减低系统表负担,因为这种操作会在一条语句中多次使用tempdb的系统表。

游标优化:
1. 尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。
2. 使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
3. 与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。

课程大纲: 第1课 数据库与关系代数 综述数据库、关系代数、查询优化技术 综述数据库调优技术 预计时间1小时 第2课 数据库查询优化技术总揽 综述查询优化技术范围,包括查询重用、查询重写规则、查询算法优化、并行查询优化等 综述逻辑查询优化,包括子查询的优化、视图重写、等价谓词重写、条件化简、连接消除、非SPJ的优化等 综述逻辑物理优化,包括单表扫描算法、两表连接算法、多表连接算法、基于代价的算法等 初步理解MySQL的查询执行计划。 预计时间1小时 第3课 查询优化技术理论与MySQL实践(一)------子查询的优化(一) 第4课 查询优化技术理论与MySQL实践(二)------子查询的优化(二) 从理论看,子查询包括的内容和范围,建立清晰的概念 从实践看,MySQL的子查询优化技术的内容和范围,明确掌握子查询优化手段 预计时间2小时,每小时一个课程段(子查询是SQL查询优化的重点内容,务必掌握好) 第5课 查询优化技术理论与MySQL实践(三)------视图重写与等价谓词重写 什么是视图重写?哪些类型的视图可以被优化?MySQL是怎么优化视图的?从而明白在MySQL中怎么写与视图相关的查询语句才能有好的效果? 什么是等价谓词重写?MySQL中怎么写WHERE子句有利于提高查询效率? 预计时间1小时 第6课 查询优化技术理论与MySQL实践(四)------条件化简 什么是条件化简?MySQL中对什么样的条件自动进行优化?如何写出可利用索引的条件语句? 预计时间1小时 第7课 查询优化技术理论与MySQL实践(五)------外连接消除、嵌套连接消除与连接消除 连接方式有些什么类型?不同类型的连接又是怎么优化的?外连接优化的条件是什么?MySQL中怎么写出可优化的连接语句?MySQL是否支持嵌套连接消除?MySQL是否支持连接消除?MySQL中书写SQL连接查询语句时的优化技巧。 预计时间1小时 第8课 查询优化技术理论与MySQL实践(六)------数据库的约束规则与语义优化 数据库的参照完整性(CHECKt NULL等)。什么是语义优化? MySQL是否支持语义优化?怎么利用语义优化的思路人工进行SQL语句的优化? 预计时间1小时 第9课 查询优化技术理论与MySQL实践(七)------非SPJ的优化 什么是非SPJ优化? 从理论看,GROUP BY、ORDER BY、LIMIT、DISTINCT等怎么被优化? MySQL中:GROUP BY是怎么优化的?ORDER BY是怎么被优化?LIMIT是怎么被优化?DISTINCT是怎么被优化? 非SPJ优化与索引的关系。 预计时间1小时 第10课 MySQL物理查询优化技术概述 从理论看,物理查询优化技术的范围。 从MySQL实践看,怎么利用物理查询优化技术对SQL查询语句调优? 本节预计会承接第9课的部分内容。 预计时间1小时 第11课 MySQL索引的利用、优化 从MySQL索引的角度出发,看各种SQL查询语句的优化怎么进行?(以前都是从语句的角度看怎么优化,现在站在索引的角度去总结SQL查询语句的优化) 预计时间1小时 第12课 表扫描与连接算法与MySQL多表连接优化实践 MySQL的单表扫描算法。MySQL的两表连接算法。MySQL的多表连接算法。 MySQL的多表连接的优化技巧。 预计时间1小时 第13课 查询优化的综合实例(一)------TPCH实践(一) 第14课 查询优化的综合实例(一)------TPCH实践(二) 以TPC-H国际标准的22条查询语句为实例,综合前面课程的内容,把所学的知识用于实践,进行综合的实战演练。 预计时间2小时(每个课时为1个小时) 第15课 关系代数对于数据库的查询优化的指导意义------查询优化技术总结 再次回到理论,从理论的高度总结关系代数理论与MySQL查询优化实践的关系。真正认识、掌握MySQL的查询优化技术,大步流星步入查询优化的高手之列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值