
执行计划是数据库根据SQL语句和相关表的统计信息制定的查询方案。该方案由查询优化器的自动分析生成。例如,如果使用SQL语句从具有100000条记录的表中搜索记录,查询优化器将在该表具有100000条记录的情况下选择索引搜索方法。全表扫描模式。
事实上,情况不同,查询分析器认为两个不同的SQL语句必须被解析两次。生成两个执行计划。所以作为程序员,您应该确保同一个查询语句在任何地方都是一致的,不超过一个空间!
我经常看到从数据库中捕获的SQL语句打印出来只要两张A4表。一般来说,这样的复杂语句通常是有问题的。我用了两页长的SQL语句来咨询原始作者。因此,他说,他花了太长时间才明白。可以想象,即使原始作者可能看到混淆的SQL语句,数据库也会看起来混淆。
通常,通常使用Select语句的结果作为子集,然后从该子集查询它。然而,根据经验,当嵌套级别超过三个级别时,查询优化器很容易给出错误的执行计划。因为它令人震惊。毕竟,像这种事情的人工智能比人的分辨率差,如果人们感到头晕,我保证不会数据库也会晕眩。
此外,执行计划可以重用,SQL语句越简单,重用的可能性就越大。只要一个字符发生变化,就需要重新解析复杂的SQL语句,然后在内存中填充大量垃圾。可以想象数据库将多么低效。
简化SQL语句的一个重要方法是使用临时表临时存储中间结果。然而,临时表的好处远不止这些。临时结果临时存储在临时表中,随后的查询在TEMPDB中。这样可以避免在程序中多次扫描主表,大大减少程序执行中阻塞更新锁的共享,减少阻塞,提高并发性能。
选择*from order header,changetime'2010-10-20000:00:01'select*from order header,changetime'2010-09-2200:00:01'
@chgtime变量可以传递任何值,使得大量类似的查询可以重用执行计划,这大大减轻了数据库解析SQL语句的负担。
凡事都有两面性。绑定变量适用于大多数OLTP处理,但是也有例外。例如,当条件中的字段是倾斜字段时。
Tilt字段指的是本专栏中的大多数值是相同的,例如人口调查,其中90%以上的少数民族是汉族。因此,如果SQL语句要查询30岁的汉族人口,则必须将该民族置于有条件的地方。在这一点上,如果使用绑定变量@国家,将有一个大问题。
设想一下,如果@national的第一个值是.,那么整个执行计划将不可避免地选择表扫描。然后,第二个值由Buyi导入,它应该只占万分之一,并且应该被索引。重用马赛德汉族,第二种也使用表扫描。这个问题被称为绑定变量窥探。建议绑定变量不用于倾斜字段。
SQL Server中的SQL语句默认为事务,在执行语句时默认提交。实际上,这是开始tran的最小形式,就像在每个句子的开头暗示一个开始tran而在结尾暗示一个commit一样。
在某些情况下,我们需要显式地声明start tran,比如同时插入、删除和更改多个表,这需要成功地修改表或不修改表。保证了数据的一致性,但是没有什么是完美的。Begin tran付出的代价是,SQL语句锁定的所有资源在提交之前都不能释放,直到提交结束。
显然,如果Begin tran的SQL语句太多,数据库的性能会很差。在提交这个大事务之前,其他语句将不可避免地被阻塞,导致很多块。
Begin tran使用以下原则:在数据一致性的前提下,启动tran的SQL语句越少越好。在某些情况下,触发器可用于同步数据,而不必启动tran。
在SQL语句中添加nolock是提高SQL Server并发性能的重要手段。因为Oracle的结构更合理,所以在Oracle中不必这么做。有一个撤消表空间的预留来保存数据。如果在修改中没有提交数据,则读取的是修改前的副本。在撤消表中,副本是空的。在这两者之间。这样,oracle的读和写不会相互影响,这也是Oracle广受赞誉的地方。为了提高并发性能,我们可以向一些查询添加nolock,这些查询允许边读边写,但是禁用DVANTAGE是我们可以读取未提交的脏数据。使用NoLoCK有三个原则。
例如,订单具有订单号、订单号和客户号CONTACDID。应该将聚合索引添加到哪个字段对于这个表,顺序号是顺序添加的。如果将聚合索引添加到订单id,那么所有新行都会在最后添加,因此不容易频繁地生成分页。但是,由于大多数查询是基于客户编号的,所以向contactid添加集群索引是有意义的。对于订单表单,contactid不是一个序列。内场。
例如,张三的联系人ID是001,所以张三的订单信息必须放在该表的第一个数据页上。如果张三今天下了新订单,订单信息不能放在表的最后一页,而是放在第一页!如果第一页满了怎么办对不起,本表中的所有数据都应重新移动,以便为这张记录留出空间。
SQL Server的索引与Oracle的索引不同。SQL Server的聚合索引实际上是根据聚集索引字段的顺序对表进行排序,这相当于Oracle对表进行组织的索引。SQL Server的聚合索引是表本身的组织形式,所以效率很高。使用这种方法,插入一个记录,其位置不是随机的,但是为了放置数据页面,如果数据页面没有空间,就会导致页面分裂。
在一种情况下,好友表的插入效率在重建后大大降低。可能是这种情况。表的聚合索引可能不建立在表的顺序字段上。表经常被存档,所以表的数据以稀疏状态存在。例如,张三时最近三个月已经下了20个订单,但只下了5个订单。归档策略是保存3个月的数据。然后,过去已经提交了15个张三时订单,留下15个空缺,当插入发生时可以重用。在这种情况下,由于空缺的可用性,将不存在分页。但是,查询性能相对较低,因为查询必须扫描这些空白空间wi。这些数据。
重新构建聚合索引后,情况发生了变化,因为重新构建聚合索引就是将表中的数据重新排列一次,所以原来的空白消失了,页面的填充率很高,插入数据经常需要分页,所以性能非常高。减少。
对于没有构建在顺序字段上的具有集群索引的表,我们是否应该给它们较低的页面填充率是否要避免重新生成聚集索引这是一个值得考虑的问题!
在添加nolock之后,您可以在插入、删除和修改的同时进行查询,但是由于同时进行插入、删除和修改,在某些情况下,一旦数据页满了,就不可避免地要进行分页。此时,nolock的查询正在发生,例如,由于页分裂,在页100上读取的记录可以被分成10。0页在读取之前被分成99页,nolock查询可能错过记录并产生跳过读取。
上述人员在添加NoLoCK后,有些操作出现了错误。据估计,这可能是因为nolock查询产生重复读取,并且两个相同的记录被插入到其他表中。当然,会有主键冲突。
关键字%yue%用于yue的前面,因此必须在整个表中扫描查询,除非必要,不要在关键词之前添加。
SQL Server 2000数据库,当我们的程序提交SQL语句时,它不使用强类型来提交这个字段的值。SQL Server 2000自动转换数据类型,这将导致传入参数和主键字段类型之间的不一致。SQL Server 2000此时可以使用全表扫描,Sql2005没有发现这个问题,但是应该注意。
SQL Server 2000只有一个连接模式,嵌套循环连接。如果结果集很小,则默认为外观。A中的每个记录都应该在B中扫描一次。实际扫描的行数对应于结果集X B结果集中的行数。所以如果两个结果集都很大,Join的结果就不好。
SQL Server 2005添加了合并连接。如果表A和表B的联接字段恰好是聚合索引所在的字段,那么只要两边拼在一起,表的顺序就被安排好了。这个连接的成本等于表A的结果集中的行数加上表B的结果集中的行数。一个相加,另一个相乘。N比嵌套循环连接工作得更好。
如果在连接的字段上没有索引,SQL 2000的效率就很低,并且SQL 2005提供了哈希连接,这相当于临时向表A和B的结果集添加索引。因此,SQL 2005的效率远远高于SQL 2000。我认为这是一个重要的原因。