`

提高SQL语句查询效率的若干建议

阅读更多

1、避免将字段设为“允许为空”

2、数据表设计要规范

3、深入分析数据操作所要对数据库进行的操作

4、尽量不要使用临时表

5、多多使用事务

6、尽量不要使用游标

7、避免死锁

8、要注意读写锁的使用

9、不要打开大的数据集

10、不要使用服务器端游标

11、在程序编码时使用大数据量的数据库

12、不要给“性别”列创建索引

13、注意超时问题

14、不要使用Select *
15、在细节表中插入纪录时,不要在主表执行Select MAX(ID)

16、尽量不要使用TEXT数据类型

17、使用参数查询

18、不要使用Insert导入大批的数据

19、学会分析查询

20、使用参照完整性

21、用INNER JOIN 和LEFT JOIN代替Where


1. 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2. 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select id from t where num=0
3. 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
4. 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num=10 or num=20 可以这样查询: select id from t where num=10 union all select id from t where num=20
5. in 和 not in 也要慎用,否则会导致全表扫描,如: select id from t where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了: select id from t where num between 1 and 3
6. .下面的查询也将导致全表扫描: select id from t where name like '%abc%' 若要提高效率,可以考虑全文检索。
7. 如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描: select id from t where num=@num 可以改为强制查询使用索引: select id from t with(index(索引名)) where num=@num
8. 应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如: select id from t where substring(name,1,3)='abc'--name以abc开头的id select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id 应改为: select id from t where name like 'abc%' select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
9. 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
10. 在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
11. 不要写一些没有意义的查询,如需要生成一个空表结构: select col1,col2 into #t from t where 1=0 这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样: create table #t(...)
12. 很多时候用 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)
13. 并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
14. 索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
15. 应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存
储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。
16. .尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了
17. 尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
18. 任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段
19. 尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。
20. 避免频繁创建和删除临时表,以减少系统表资源的消耗。
21. 应尽量避免在where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如: select id from t where num/2=100 应改为: select id from t where num=100*2
22. 临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
23. 在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
24. 如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
25. 尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。
26. 使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效
27. 与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。
28. 在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。
29. 尽量避免大事务操作,提高系统并发能力。
30. 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理
31. 注意union和union all的区别。union比union all多做了一步distinct操作。能用union all的情况下尽量不用union
32. 查询时尽量不要返回不需要的行、列。另外在多表连接查询时,尽量改成连接查询,少用子查询
33. 尽量少用视图,它的效率低。
34. 创建合理的索引,对于插入或者修改比较频繁的表,尽量慎用索引。因为如果表中存在索引,插入和修改时也会引起全表扫描。索引一般使用于where后经常用作条件的字段上。
35. Between在某些时候比IN速度更快,Between能够更快地根据索引找到范围。
select * from chineseresume where title in ('男','女') Select * from chineseresume where between '男' and '女'
36. WHERE后面的条件顺序影响WHERE子句后面的条件顺序对大数据量表的查询会产生直接的影响,尽量将范围小的条件放在前面
37. 没有必要时不要用DISTINCT和ORDER BY
38. 慎用临时表,临时表存储于tempdb库中,操作临时表时,会引起跨库操作。尽量用结果集和表变量来代替它。

分享到:
评论

相关推荐

    Informix11_SQL性能调整.pdf

    INFORMIX 的 SQL 执行计划,如何通过统计信息,SQLDirectives 调整执行计划,如何通过 SQL Drill-down 监控 SQL 的执行效率,并且总结了书写 SQL 语句时若干需要注意的地方,可以作为一个实用的 SQL Cheklist 使用。...

    Informix 11 SQL性能调整

    过SQL Drill-down监控SQL的执行效率,并且总结了书写SQL语句时若干需要注意的地方, 可以作为一个实用的SQL Cheklist使用。本文尽量减少理论的论述而注重实例分析和实际操 作,相信对大家一定会有所帮助

    SQL编程思想:基于5种主流数据库代码实现.docx

    查询优化可以通过优化查询语句和数据库索引等方式进行提高。 3. SQL 编程思想的核心要点 SQL 编程思想的核心要点在于结构化查询语言的设计和实现。结构化查询语言使得程序员可以以一种统一的方式对数据库进行操作...

    自考数据库系统原理 第五章 SQL语言 课后习题答案

    共享变量有宿主语言程序定义,再用SQL的DECLARE语句说明,SQL语句就可引用这些变量传递数据库信息。 游标和卷游标 游标是与某一查询结果相联系的符号名,用于把集合操作转换成单记录处理方式。卷游标是在推进时...

    SQL存储过程

    用户存储过程可以完成以下功能:接受输入参数并返回多个输出值、包含若干T-SQL语句,用以完成特定的SQL Server操作,其中可以有对其他存储过程的调用、返回一个指示成功与否及失败原因的状态代码给调用它的过程。...

    入门存储过程

    sql语句执行的时候要先编译,然后执行。存储过程就是编译好了的一些sql语句。应用程序需要用的时候直接调用就可以了,所以效率会高。 存储过程介绍 存储过程是由流控制和SQL语句书写的过程,这个过程经编译和...

    MYSQL数据库高级应用宝典含实例(索引、视图、触发器、游标和存储过程)

    存储过程是一种预编译的SQL语句,它可以在数据库服务器上执行。存储过程的优点是: * 提高查询效率 * 实现业务逻辑的自动执行 * 提高数据安全性 存储过程的创建: * CREATE PROCEDURE proc_name (param1,param2,....

    深度数据库设计及oracle总结

    包含Oracle的SQL语句执行效率问题查找与解决方法文档,oracle性能优化总结文档,数据库设计方法文档,SQL语句全优化文档,数据库设计中的14个实用技巧文档,优化Oracle库表设计的若干方法等...对于想系统研究数据库和...

    DBA的oracle数据设计与优化

    Database Design.ppt,Oracle的SQL语句执行效率问题查找与解决方法.doc,Oracle数据库设计要做到五戒.txt,oracle性能优化总结.doc,SQL语句全优化.doc,数据库设计中的14个实用技巧.doc,优化Oracle库表设计的若干方法....

    oracle性能优化资料大全(更全最深)

    oracle专业优化文档,Oracle的SQL语句执行效率问题查找与解决方法文档,oracle性能优化总结文档,数据库设计方法文档,SQL语句全优化文档,数据库设计中的14个实用技巧文档,优化Oracle库表设计的若干方法等......

    数据库答案6.docx

    1.SQL 语言引入了视图的概念,下述说法正确的是( )。 A. 视图是由若干数据表组成的,独立存储在数据库中 ... 视图简化用户观点,但不提高查询效率 2.数据库中只存放视图的( )。 A定义 B操作 C结果 D数据

    支持多数据库的ORM框架ef-orm.zip

    EF的设计的一个主要目的是提高开发效率,减少编码工作,让开发者“零配置”“少编码”的操作数据库大部分功能。 例如:数据库查询条件的传入问题是所有ORM框架都不能回避的一个问题,所以我经常在想——既然我们...

    数据库原理及应用复习重点

    数据 normalization 的目的是提高数据的一致性、减少数据冗余、提高查询效率等。 * 习题 6:什么是第一范式(1NF)、第二范式(2NF)、第三范式(3NF)? 第一范式(1NF)要求每个表中的每个列都只能包含原子值;第...

    AppFramework数据库访问组件_代码生成插件_V1.1.rar

    &lt;br&gt;IBatisNet是一个轻量级ORMap工具,它把所有的SQL脚本以模板的方式集中到若干个XML配置文件里,用反射的方式向把C#类实体对象属性与SQL模板的参数绑定,动态生成参数化的SQL语句发送给数据库执行,查询的结果...

    AppFramework_V1.0_New

    &lt;br&gt;IBatisNet是一个轻量级ORMap工具,它把所有的SQL脚本以模板的方式集中到若干个XML配置文件里,用反射的方式向把C#类实体对象属性与SQL模板的参数绑定,动态生成参数化的SQL语句发送给数据库执行,查询的结果...

    AppFramework_V1.0

    &lt;br&gt;IBatisNet是一个轻量级ORMap工具,它把所有的SQL脚本以模板的方式集中到若干个XML配置文件里,用反射的方式向把C#类实体对象属性与SQL模板的参数绑定,动态生成参数化的SQL语句发送给数据库执行,查询的结果...

    asp在线考试系统(asp+access实现)

    但是所有SQL语句都必须由数据库服务器独立地执行。这就意味着客户端应用必须把每条查询发送到数据库服务器,等待它处理这个查询,接收结果,做一些运算,然后给服务器发送另外一条查询。所有这些东西都会产生进程间...

    asp学习相关资料大全

    虽然很多数据库都对SQL语句进行了再开发和扩展,但是包括Select, Insert, Update, Delete, Create,以及Drop在内的标准的SQL命令仍然可以被用来完成几乎所有的数据库操作。 3.1.3 B/S结构介绍 B/S(Browser/Server...

    ASP设计在线考试系统OnlineTest

    但是所有SQL语句都必须由数据库服务器独立地执行。这就意味着客户端应用必须把每条查询发送到数据库服务器,等待它处理这个查询,接收结果,做一些运算,然后给服务器发送另外一条查询。所有这些东西都会产生进程间...

    易搜索 站内全文检索搜索引擎 v1.0.rar

    一般的搜索都是通过SQL语句中的LIKE关键字实现搜索功能,但LIKE在数量较大时,速度很慢,甚至会导致服务器磐机。 3、 搜索不到正文。与第二条类似,LIKE关键字只能对短文本进行比较操作,而对正文这种长文本,不能...

Global site tag (gtag.js) - Google Analytics