高速扫描的出现对数据库查询来说是意义重大,高速扫描实现了数据库查询的高速化发展,也使数据库查询性能优化了,下面就为大家介绍高级扫描。
一、高级扫描使用举例
通常情况下在数据查询的时候,数据库会利用索引或者通过全表扫描来查找数据。但是如果需要的数据在数据库中存储不连续或者需要查找的记录比较多时,此时索引的效果就会大打折扣。在这种情况下,数据库查询优化器可能会采用全表扫描来代替索引。但是众所周知,全表扫描的效率是比较低下的。为此在SQL Server数据库的企业版中,提出了一个高级扫描的处理方式。简单的说,高级扫描可以让多项查询任务共享完全表扫描。笔者先给大家举一个例子,然后再跟大家谈谈隐藏在其背后的秘密。
如在上图中,一个表中的记录比较多有40000页。用户甲需要查询这个表中的记录,假设其采用了全表扫描。当数据库查询到20000页的时候,用户乙也需要这个表中的数据,那么又触发了一个全表扫描。此时如果没有采用高级扫描技术的话,则用户乙的SQL语句必须要等到用户甲的执行完毕后才会执行。而如果采用了高级扫描技术的话,则数据库在从20000页开始的全表扫描中,会把扫描的结果分成两个副本,分别给用户甲与乙。然后当第30000页的时候,用户丙也参与进来了。同理数据库引擎会把从30000页开始的扫描结果分为三个副本,分别给三个用户。当整个表扫描完成之后,数据库引擎就会把结果返回给用户甲。然后再从头开始扫描,当扫描到20000页的时候,就会把上次扫描的20000页到400000页的结果合并起来然后返回给用户乙。扫描到300000页的时候就会把与上次扫描到的结果合并起来返回给用户丙。
可见如果在不同高级扫描功能的话,则不同用户在不同时刻的查询请求,可能需要对某个表进行全表扫描三次。而在上面这个案例中,则知需要对这个表扫描2次都不到。为此当多个对同一个表进行全表扫描时,高级扫描工具可以明显提高数据库的运行性能。
二、高级扫描实现的秘密
可见高级扫描其主要就是通过共享全表扫描技术来实现的。也就是说,当SQL语句的执行计划需要扫描表中的数据页(即全表扫描),并且数据库引擎检测到其他查询执行计划正在扫描这个表中的时候(如上例中用户乙、丙参与进来),则数据库引擎就会在第二个扫描的当前位置将第二个扫描插入到第一个扫描中(此时数据库引擎会会把扫描的结果产生一个副本)。数据库引起会一次读取一页,并加每一页的行传递给多个执行计划,一直到当前扫描结束。
此时,第一个扫描(用户甲)已经完全结束,数据库引擎就会把扫描的结果传递给用户甲的进程。但是此时数据库乙还不能够把结果返回给用户乙,因为在用户甲开始查询到用户乙递交SQL语句中间,可能会有用户对前面几页的数据进行修改。为此数据库引擎需要对先前的页进行重新扫描,以防止数据的误读。为此第二个查询计划必须发起第二个全表扫描,检索第二个执行计划加入第一次扫描正在进行的扫描之前读取的数据页。即第二个执行计划的扫描将绕回到第一个数据页,并从这里开始扫描,直到其加入到第一个扫描时的位置。然后数据库引擎会把扫描到的结果返回给第二个查询计划,依次类推。在实际工作中,可以按这种方式组合任意数量的扫描。其实这种扫描很想走马灯,为此我们又把高级扫描戏称为全表扫描。可见在这种情况下,如果多个用户在一次全表扫描的过程中查询同一个表,则可以减少全表扫描的次数。如果在没有高级扫描的情况下,像上面的用户甲、乙、丙都必须要争用缓冲区空间并因此导致硬盘或者内存的争用等等。然后数据库引擎会分别为每一个用户读取依次相同的页,而不是每次读取的结果有多个用户共享。显然跟高级扫描比起来,这种处理方式其效率会低很多。
三、高级扫描的弊端与解决方式
虽然高级扫描会提高数据库的查询性能,但是这种处理机制也会有一个弊端,即会导致查询结果记录顺序的混乱。如上面这个例子中,如果三个用户采用的都是同一个查询语句的话,则其最后返回的结果虽然记录的内容是相同的,但是显示的记录顺序是不同的(假设没有采用排序语句)。这可能会给用户一种误解,以为各自查到的是不同的内容。为什么会产生这种情况呢?为了说们这个问题的原因,笔者就对表中的内容进行简化。假设某一张表中有三条记录,序号分别为1、2、3。
现在用户甲需要查询这个表中的内容,进行了一次全表扫描。当第一条记录查询完毕之后,用户乙也需要查询这个表。从这次开始的后续查询中,数据库引擎会把结果同时发送给用户甲与乙两个查询计划。也就是说,用户乙此时扫描的第一个结果是序号为2的记录。然后用户丙又插了进来,那么这个时候数据库引擎返回给用户丙执行计划的第一条记录就是序号为3的记录了。第一次扫描完毕后,再重新进行第二次扫描,然后把序号为1的记录返回给用户乙。最后用户甲显示的记录顺序为1、2、3;而用户乙显示的记录顺序为2、3、1;用户丙显示的记录顺序为3、2、1。当记录比较少的时候,用户还可以一目了然的指导查询结果是相同的,只是顺序颠倒了而已。但是如果记录比较多的情况下,则用户丙很可能会误认为其找到的记录跟甲是不同的。因为顺序混乱,所以不能够清楚的判断所查找的记录是否相同。
为此在实际工作中,需要克服这个弊端。最简单的方式就是采用order by语句对查询的结果进行扫描。但是众所周知,对记录进行排序会增加数据库额外的开销,会抵消高级扫描所带来的性能提升的效果。故通常情况下对于可能需要用到高级扫描的SQL语句,不会采用order by等排序语句,除非用户非常明确的有这方面的需要,才会把这个语句加入进去。另外需要注意的是,有些汇总语句,如Group By等也会对记录进行自动排序,这也会增加额外的负担。但是一般来说,即使是需要对查询结果进行排序,那么排序过程中的开销相比多次全表扫描的开销来说,还是要小的多。也就是说,在高级扫描后进行排序来解决这个记录显示顺序不一致的情况,仍然是可行的。
四、影响高级扫描效果的因素
如上的分析中,在一个查询计划的执行过程中,如果越多的查询计划插入到其中来,那么这个高级扫描技术的效果就越佳。相反,如果一个查询计划完成后,仍然没有用户加入到这个查询计划中,那么这个高级扫描的功能就根本没有发挥出来。此时查询就只是一个简单的全表扫描。为此对这个高级扫描的效果,直接跟用户的参与度相关。如果在一个比较短的时间间隔内,比较多的用户发起了对一个表的查询,那么高级扫描的效果才能够体现出来。为此数据库管理员需要知道,并不是在任何时候数据库系统上实现高级扫描就可以实现比较高的数据库性能。而是需要跟数据库的实际应用以及员工的作业有关。
为此企业如果比较多的用户需要对某张表进行查询的时候,那么就需要考虑是否能够采用高级扫描。如在一个ERP系统中,其产品信息有几百万条。有多个用户需要查询这个产品信息表中的内容,需要把查票信息导出来以作他用。此时各个部门的用户如果在前后时间间隔不是很大的情况下,对这个表发起查询作业。那么此时就可以利用高级扫描工具来共享扫描对结果,减少全表扫描此时,提高扫描结果。
除了用户人数之外,还需要注意的是记录的内容多少也跟这个高级扫描的效果有关。如高纪录比较到,则这个全表扫描的时间就比较长。而执行计划长了,则在这个执行计划的执行过程中参与的用户可能会越多。那无疑也可以提高高级扫描的效果。此时可以起到一个累加的效果,用户总的等待时间会随着参与到这个查询计划中来的用户数量而减少。人数越多,用户总的等待时间比全表扫描需要花费的时间少的会更多。
以上就是我要为大家介绍的全部内容,希望能够帮到大家,以后有什么好的东西会继续跟大家分享。
【编辑推荐】