SQL Server 数据操作

一、数据访问操作

SQL Server有二种索引:聚集索引和非聚集索引。二者的差别在于:【聚集索引】直接决定了记录的存放位置, 或者说:根据聚集索引可以直接获取到记录。【非聚集索引】保存了二个信息:1.相应索引字段的值,2.记录对应聚集索引的位置(如果表没有聚集索引则保存记录指针)。 因此,如果能通过【聚集索引】来查找记录,显然也是最快的。

SQL Server 会有以下方法来查找您需要的数据记录:
1. 【Table Scan】:遍历整个表,查找所有匹配的记录行。这个操作将会一行一行的检查,当然,效率也是最差的。发生于堆表,并且没有可用的索引可用时,会发生表扫描,表示整个表扫描一次
2. 【Index Scan】:根据索引,从表中过滤出来一部分记录,再查找所有匹配的记录行,显然比第一种方式的查找范围要小,因此比【Table Scan】要快。
3. 【Index Seek】:根据索引,定位(获取)记录的存放位置,然后取得记录,因此,比起前二种方式会更快。
4. 【Clustered Index Scan】:和【Table Scan】一样。注意:不要以为这里有个Index,就认为不一样了。 其实它的意思是说:按聚集索引来逐行扫描每一行记录,因为记录就是按聚集索引来顺序存放的。 而【Table Scan】只是说:要扫描的表没有聚集索引而已,因此这二个操作本质上也是一样的。发生于聚集表,也相当于全表扫描操作,但在针对聚集列的条件如(WHERE Id > 10)等操作时,效率会较好。加了聚集索引之后,表就由堆表变成了聚集表。我们知道聚集表的数据存在于聚集索引的叶级节点。因此,聚集扫描与表扫描其实差别不大,要说差别大,也得看where条件里是什么,以后返回的数据
5. 【Clustered Index Seek】:直接根据聚集索引获取记录,最快!扫描聚集索引中特定范围的行。

6.【书签查找】:我们已经知道,当在非聚集索引中并非覆盖和包含所需全部的列时,SQL Server会选择,直接进行聚集索引扫描获得数据,还是先去非聚集索引找到聚集索引键,然后利用聚集索引找到数据。

上面的过程可以理解为:首先通过非聚集索引找到所求的行,但这个索引并不包含所有的列,因此还要额外去基本表中找到这些列,因此要进行键查找,如果基本表是以堆进行组织的,那么这个键查找(Key Lookup)就会变成RID查找(RID Lookup),键查找和RID查找统称为书签查找。不过有时当非聚集索引返回的行数过多时,SQL Server可能会选择直接进行聚集索引扫描了。

所以,当发现某个查询比较慢时,可以首先检查哪些操作的成本比较高,再看看那些操作在查找记录时, 是不是【Table Scan】或者【Clustered Index Scan】,如果确实和这二种操作类型有关,则要考虑增加索引来解决了。 不过,增加索引后,也会影响数据表的修改动作,因为修改数据表时,要更新相应字段的索引。所以索引过多,也会影响性能。 还有一种情况是不适合增加索引的:某个字段用0或1表示的状态。例如可能有绝大多数是1,那么此时加索引根本就没有意义。 这时只能考虑为0或者1这二种情况分开来保存了,分表或者分区都是不错的选择。

如果不能通过增加索引和调整表来解决,那么可以试试调整语句结构,引导SQL Server采用其它的查询方案去执行。 这种方法要求: 1.对语句所要完成的功能很清楚, 2.对要查询的数据表结构很清楚, 3.对相关的业务背景知识很清楚。 如果能通过这种方法去解决,当然也是很好的解决方法了。不过,有时SQL Server比较智能,即使你调整语句结构,也不会影响它的执行计划。

如何比较二个相同功能的SQL语句的性能好坏呢,我建议采用二种方法: 1. 直接把二个查询语句放在【SQL Server Management Studio】,然后去看它们的【执行计划】,SQL Server会以百分比的方式告诉你二个查询的【查询开销】。 这种方法简单,通常也是可以参考的,不过,有时也会不准,具体原因请接着往下看(可能索引统计信息过旧)。
2. 根据真实的程序调用,写相应的测试代码去调用:这种方法就麻烦一些,但是它更能代表现实调用情况, 得到的结果也是更具有参考价值的,因此也是值得的。

 

二、流聚合操作

1:流聚合

流聚合:在相应排序的流中,计算多组行的汇总值。

  所有的聚合函数(如COUNT(),MAX())都会有流聚合的出现,但是其不会消耗IO,只有消耗CPU。

2:计算标量

计算标量:根据行中的现有值计算新值。比如COUNT()函数,多一行,行数就加1咯。

  除MIN和MAX函数之外的聚合函数都要求流聚合操作后面跟一个计算标量。

3:散列聚合

  对于加了Group by的子句,因为需要数据按照group by 后面的列有序,就需要Sort来保证排序。注意,Sort操作是占用内存的操作,当内存不足时还会去占用tempdb。SQL Server总是会在Sort操作和散列匹配中选择成本最低的

  对于数据量比较大时,SQL Server选择的是哈希匹配。

  在内存中建立好散列表后,会按照group by后面的值作为键,然后依次处理集合中的每条数据,当键在散列表中不存在时,向散列表添加条目,当键已经在散列表中存在时,按照规则(规则是聚合函数,比如Sum,avg什么的)计算散列表中的值(Value)

4:排序

  对于加了Group by的子句,当数据量比较少时,例如执行以下语句,新建一个只有数十条记录的与Person一样的表

三、连接

浅谈SQL Server中的三种物理连接操作

四、并行

当多个表连接时,SQL Server还允许在多CPU或多核的情况下允许查询并行,这样无疑提高了效率。

posted @ 2014-09-11 11:00  LeonGo  阅读(251)  评论(0编辑  收藏  举报