sql的优化

执行计划:数据库根据sql语句和相关表的统计信息,作出一个查询方案,由查询优化器自动分析产生。

优化sql,就是减少资源消耗,加快查询效果。

效率原则:一次解析,多次重用。

1,统一sql语句(大小写,空格等不同都会产生两个执行计划)

2,sql不能太长,不能太过冗余。

3,考虑临时表暂存中间结果

4,OLTP系统(联机事务处理系统,相向交易的处理系统)中的sql语句绑定变量@chgtime传递任何值,大量类似的查询就重用该执行计划。

5,绑定变量窥测,“倾斜字段”指该列中的绝大多数的值都是相同的,比如一张人口调查表,其中“民族”这列,90%以上都是汉族。那么如果一个SQL语句要查询30岁的汉族人口有多少,那“民族”这列必然要被放在where条件中。这个时候如果采用绑定变量@nation会存在很大问题。所以这样的情况尽量的少用。

6,begin tran 和commit  多条sql一起修改的时候使用这个,再用commit结束。但是其中不要太多,防止站住太多的表单,导致阻塞。

7,部分查询语句加上nolock

在SQL语句中加nolock是提高SQL Server并发性能的重要手段,查询的结果用于“插、删、改”的不能加nolock !查询的表属于频繁发生页分裂的,慎用nolock !能采用临时表提高并发性能的,不要用nolock 

8 , 聚集索引没有建在表的顺序字段上,该表容易发生页分裂

比如订单表,有订单编号orderid,也有客户编号contactid,那么聚集索引应该加在哪个字段上呢?对于该表,订单编号是顺序添加的,如果在orderid上加聚集索引,新增的行都是添加在末尾,这样不容易经常产生页分裂。然而,由于大多数查询都是根据客户编号来查的,因此,将聚集索引加在contactid上才有意义。而contactid对于订单表而言,并非顺序字段。

比如“张三”的“contactid”是001,那么“张三”的订单信息必须都放在这张表的第一个数据页上,如果今天“张三”新下了一个订单,那该订单信息不能放在表的最后一页,而是第一页!如果第一页放满了呢?很抱歉,该表所有数据都要往后移动为这条记录腾地方。

SQL Server的索引和Oracle的索引是不同的,SQL Server的聚集索引实际上是对表按照聚集索引字段的顺序进行了排序,相当于oracle的索引组织表。SQL Server的聚集索引就是表本身的一种组织形式,所以它的效率是非常高的。也正因为此,插入一条记录,它的位置不是随便放的,而是要按照顺序放在该放的数据页,如果那个数据页没有空间了,就引起了页分裂。所以很显然,聚集索引没有建在表的顺序字段上,该表容易发生页分裂。

曾经碰到过一个情况,一位哥们的某张表重建索引后,插入的效率大幅下降了。估计情况大概是这样的。该表的聚集索引可能没有建在表的顺序字段上,该表经常被归档,所以该表的数据是以一种稀疏状态存在的。比如张三下过20张订单,而最近3个月的订单只有5张,归档策略是保留3个月数据,那么张三过去的 15张订单已经被归档,留下15个空位,可以在insert发生时重新被利用。在这种情况下由于有空位可以利用,就不会发生页分裂。但是查询性能会比较低,因为查询时必须扫描那些没有数据的空位。

重建聚集索引后情况改变了,因为重建聚集索引就是把表中的数据重新排列一遍,原来的空位没有了,而页的填充率又很高,插入数据经常要发生页分裂,所以性能大幅下降。

对于聚集索引没有建在顺序字段上的表,是否要给与比较低的页填充率?是否要避免重建聚集索引?是一个值得考虑的问题!

9,合理利用like模糊查询

10,数据类型的隐式转化影响效率。

11,sql Server 表的连接三种方式

  1. Merge Join
  2. Nested Loop Join
  3. Hash Join

SQL Server 2000只有一种join方式——Nested Loop Join,如果A结果集较小,那就默认作为外表,A中每条记录都要去B中扫描一遍,实际扫过的行数相当于A结果集行数x B结果集行数。所以如果两个结果集都很大,那Join的结果很糟糕。

SQL Server 2005新增了Merge Join,如果A表和B表的连接字段正好是聚集索引所在字段,那么表的顺序已经排好,只要两边拼上去就行了,这种join的开销相当于A表的结果集行数加上B表的结果集行数,一个是加,一个是乘,可见merge join 的效果要比Nested Loop Join好多了。

12,from后面最后一个表会被先处理(选取条数少的作为基础表),如果3个以上的,就选交叉表(insersection table)作基础表

13,where的表连接写在最前面,过滤大量条件。

14,select 子句避免使用*

15,减少访问数据库次数

16,在sql*plus,sql*from和pro*c设置Arraysize参数。

17,使用decode函数减少处理时间

18,删除重复记录

19,尽量多的使用commit

a. 回滚段上用于恢复数据的信息。

b. 被程序语句获得的锁。

c. redo log buffer 中的空间。 Chinaz@com

d. Oracle为管理上述3种资源中的内部花费。

20,内部函数提升

21,用EXISTS替代IN、用NOT EXISTS替代NOT IN:

22,sql语句用大写

23,>=代替>,避免使用“+”

24,union或者in替换or

25,避免使用耗费资源的操作:

26,优化group by

等等。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值