作家
登录

优化SQL查询:如何写出高性能SQL语句

作者: 来源: 2017-07-12 15:02:18 阅读 我要评论

可见,如不雅Begin tran套住的SQL语句太多,那数据库的机能就糟糕了。在该大年夜事务提交之前,必定会壅塞其余语句,造成block很多。

Begin tran应用的原则是,在包管数据一致性的前提下,begin tran 套住的SQL语句越少越好!有些情况下可以采取触发器同步数据,不必定要用begin tran。

在SQL语句中加nolock是进步SQL Server并发机能的重要手段,在oracle中并不须要如许做,因为oracle的构造更为合理,有undo表空间保存“数据前影”,该数据如不雅在修改中还未commit,那么你读到的是它修改之前的副本,该副本放在undo表空间中。如许,oracle的读、写可以做到互不影响,这也是oracle 广受称赞的处所。SQL Server 的读、写是会互相壅塞的,为了进步并发机能,对于一些萌芽,可以加上nolock,如许读的时刻可以许可写,但缺点是可能读到未提交的脏数据。应用 nolock有3条原则。

(1) 萌芽的结不雅用于“插、删、改”的不克不及加nolock !

(2) 萌芽的表属于频繁产生页决裂的,慎用nolock !

  1. select*from dual 
  2.  
  3. select*From dual 

(3) 应用临时表一样可以保存“数据前影”,起到类似oracle的undo表空间的功能,

能采取临时表进步并发机能的,不要用nolock 。

9、 集合索引没有建在表的次序字段上,该表轻易产生页决裂

比如订单表,有订单编号orderid,也有客户编号contactid,那么集合索引应当加在哪个字段上呢?对于该表,订单编号是次序添加的,如不雅在orderid上加集合索引,新增的行都是添加在末尾,如许不轻易经常产生页决裂。然而,因为大年夜多半萌芽都是根据客户编号来查的,是以,将集合索引加在contactid上才有意义。而contactid对于订单表而言,并非次序字段。

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

SQL Server的索引和Oracle的索引是不合的,SQL Server的集合索引实际上是对表按照集合索引字段的次序进行了排序,相当于oracle的索引组织表。SQL Server的集合索引就是表本身的一种组织情势,所以它的效力是异常高的。也正因为此,插入一笔记录,它的地位不是随便放的,而是要按照次序放在该放的数据页,如不雅那个数据页没有空间了,就引起了页决裂。所以很显然,集合索引没有建在表的次序字段上,该表轻易产生页决裂。

曾经碰着过一个情况,一位哥们的某张表重建索引后,插入的效力大年夜幅降低了。估计情况大年夜概是如许的。该表的集合索引可能没有建在表的次序字段上,该表经常被归档,所以该表的数据是以一种稀少状况存在的。比如张三下过20张订单,而比来3个月的订单只有5张,归档策略是保存3个月数据,那么张三以前的 15张订单已经被归档,留下15个空位,可以在insert产生时从新被应用。在这种情况下因为有空位可以应用,就不会产生页决裂。然则萌芽机能会比较低,因为萌芽时必须扫描那些没稀有据的空位。

重建集合索引后情况改变了,因为重建集合索引就是把表中的数据从新分列一遍,本来的空位没有了,而页的填充率又很高,插入数据经常要产生页决裂,所以机能大年夜幅降低。

对于集合索引没有建在次序字段上的表,是否要授与比较低的页填充率?是否要避免重建集合索引?是一个值得推敲的问题!

10、加nolock后萌芽经常产生页决裂的表,轻易产生跳读或反复读

加nolock后可以在“插、删、改”的同时进行萌芽,然则因为同时产生“插、删、改”,在某些情况下,一旦该数据页满了,那么页决裂弗成避免,而此时nolock的萌芽正在产生,比如在第100页已经读过的记录,可能会因为页决裂而分到第101页,这有可能使得nolock萌芽在读101页时反复读到该条数据,产生“反复读”。同理,如不雅在100页上的数据还没被读到就分到99页去了,那nolock萌芽有可能会漏过该记录,产生“跳读”。

膳绫擎提到的哥们,在加了nolock后一些操作出现报错,估计有可能因为nolock萌芽产生了反复读,2条雷同的记录去插入其余表,当然会产生主键冲突。

11、应用like进行模糊萌芽时应留意

有的时刻会须要进行一些模糊萌芽比如

  1. select*from contact where username like ‘%yue%’ 

关键词%yue%,因为yue前面用到了“%”,是以该萌芽必定走全表扫描,除非须要,不然不要在关键词前加%,

(1) 连接字段尽量选择集合索引地点的字段

sql server2000的数据库,我们的法度榜样在提交sql语句的时刻,没有应用强类型提交这个字段的值,由sql server 2000主动转换数据类型,会导致传入的参数与主键字段类型不一致,这个时刻sql server 2000可能就会应用全表扫描。Sql2005膳绫腔有发明这种问题,然则照样应当留意一下。

13、SQL Server 表连接的三种方法

(1) Merge Join

(3) Hash Join

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


  推荐阅读

  Linux的EXT4 文件系统的历史、特性以及最佳实践

每个 EXT2 分区中的空间被分为柱面组(cylinder group),它许可更精细地治理数据空间。 根据我的经验,每一组大年夜小平日约为 8MB。 下面的图 1 显示了一个柱面组的根本构造。 柱面中的数>>>详细阅读


本文标题:优化SQL查询:如何写出高性能SQL语句

地址:http://www.17bianji.com/lsqh/36171.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)