SQL语句性能优化实例.pdf
《SQL语句性能优化实例.pdf》由会员分享,可在线阅读,更多相关《SQL语句性能优化实例.pdf(14页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、SQL 语句性能优化实例 1,对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。2,应尽量避免在 where 子句中对字段进行 null 值判断,创建表时NULL 是默认值,但大多数时候应该使用 NOT NULL,或者使用一个特殊的值,如 0,-1 作为默 认值。3,应尽量避免在 where 子句中使用!=或操作符,MySQL 只有对以下操作符才使用索引:,=,BETWEEN,IN,以及某些时候的 LIKE。4,应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,可以 使用 UNION 合并查询
2、:select id from t where num=10 union all select id from t where num=20 5,in 和 not in 也要慎用,否则会导致全表扫描,对于连续的数值,能用 between 就不要用 in 了:Select id from t where num between 1 and 3。6,下 面 的 查 询 也 将 导 致 全 表 扫 描:select id from t where name like%abc%或者 select id from t where name like%abc若要提高效率,可以考虑全文检索。而 select
3、 id from t where name like abc%才用到索引。7,如果在 where 子句中使用参数,也会导致全表扫描。8,应尽量避免在 where 子句中对字段进行表达式操作,应尽量避免在where 子句中对字段进行函数操作 9,很多时候用 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)10,索引固然可以提高相应的 select 的效率,但同时
4、也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6 个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。11,应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。12,尽量使用数字型字段,若只含数值信息的字段尽量不要设
5、计为字符型,这会降低查询和连接的性能,并会增加存储开销。13,尽可能的使用 varchar/nvarchar 代替 char/nchar,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。14,最好不要使用”“返回所有:select from t,用具体的字段列表代替“*”,不要返回用不到的任何字段。15,尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。16,使用表的别名(Alias):当在 SQL 语句中连接多个表时,请使用表的别名并把别名前缀于每个 Column 上.这样一来,就可以减少解析的时间并减少那些由 C
6、olumn 歧义引起的语法错误。17,使用“临时表”暂存中间结果 简化 SQL 语句的重要方法就是采用临时表暂存中间结果,但是,临时表的好处远远不止这些,将临时结果暂存在临时表,后面的查询就在tempdb 中了,这可以避免程序中多次扫描主表,也大大减少了程序执行中“共享锁”阻塞“更新锁”,减少了阻塞,提高了并发性能。18,一些 SQL 查询语句应加上 nolock,读、写是会相互阻塞的,为了提高并发性能,对于一些查询,可以加上 nolock,这样读的时候可以允许写,但缺点是可能读到未提交的脏数据。使用 nolock 有 3 条原则。查询的结果用于“插、删、改”的不能加 nolock!查询的表属
7、于频繁发生页分裂的,慎用 nolock!使用临时表一样可以保存“数据前影”,起到类似 Oracle 的 undo 表空间的功能,能采用临时表提高并发性能的,不要用 nolock。19,常见的简化规则如下:不要有超过 5 个以上的表连接(JOIN),考虑使用临时表或表变量存放中间结果。少用子查询,视图嵌套不要过深,一般视图嵌套不要超过 2 个为宜。20,将需要查询的结果预先计算好放在表中,查询的时候再 Select。这在 SQL7.0 以前是最重要的手段。例如医院的住院费计算。21,用 OR 的字句可以分解成多个查询,并且通过 UNION 连接多个查询。他们的速度只同是否使用索引有关,如果查询需
8、要用到联合索引,用UNION all 执行的效率更高.多个 OR 的字句没有用到索引,改写成UNION 的形式再试图与索引匹配。一个关键的问题是否用到索引。22,在 IN 后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数。23,尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中的 SQL 语句,是控制流语言的集合,速度当然快。反复执行的动态 SQL,可以使用临时存储过程,该过程(临时表)被放在Tempdb 中。24,当服务器的内存够多时,配制线程数量=最大连接数+5,这样能发
9、 挥 最 大 的 效 率;否 则 使 用 配 制 线 程 数 量=”,不要使用“”。28,索引的使用规范:索引的创建要与应用结合考虑,建议大的 OLTP表不要超过 6 个索引;尽可能的使用索引字段作为查询条件,尤其是聚簇索引,必要时可以通过 index index_name 来强制指定索引;避免对大表查询时进行 table scan,必要时考虑新建索引;在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用;要注意索引的维护,周期性重建索引,重新编译存储过程。29,下列 SQL 条件语句中的列都建有恰当的索引,
10、但执行速度却非常慢:SELECT*FROM record WHERE substrINg(card_no,1,4)=5378(13秒)SELECT*FROM record WHERE amount/30 1000(11 秒)SELECT*FROM record WHERE convert(char(10),date,112)=19991201(10 秒)分析:WHERE 子句中对列的任何操作结果都是在 SQL 运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被 SQL 优化器优化,使用索引,避免表搜索,因此将 SQL 重写成下
11、面这样:SELECT*FROM record WHERE card_no like 5378%(1 秒)SELECT*FROM record WHERE amount 1000*30(1 秒)SELECT*FROM record WHERE date=1999/12/01(1 秒)30,当有一批处理的插入或更新时,用批量插入或批量更新,绝不会一条条记录的去更新!31,在所有的存储过程中,能够用 SQL 语句的,我绝不会用循环去实现!(例如:列出上个月的每一天,我会用 connect by 去递归查询一下,绝不会去用循环从上个月第一天到最后一天)32,选择最有效率的表名顺序(只在基于规则的优化器
12、中有效):oracle 的解析器按照从右到左的顺序处理 FROM 子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在 FROM 子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有 3 个以上的表连接查询,那就需要选择交叉表(intersection table)作为基础表,交叉表是指那个被其他表所引用的表.33,提高 GROUP BY 语句的效率,可以通过将不需要的记录在 GROUP BY 之前过滤掉.下面两个查询返回相同结果,但第二个明显就快了许多.低效:SELECT JOB,AVG(SAL)FROM EMP GROUP BY
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- SQL 语句 性能 优化 实例
限制150内