SQL Server 原理

发表于:2009-8-10 10:45

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:网络转载

分享:

  查询执行器来负责SQL的执行。因为SQL的执行要涉及到事务、锁、等待、CPU调度,内存页失效影响、I/O存取影响,所以查询执行器会协调很多其他模块,但各个模块来负责处理,而查询执行器并不真正全部包办,否则让事务管理器、锁管理器、索引管理器、页面文件管理器、缓冲管理器、行管理器、日志管理器干吗去。

  查询执行器是查询引擎的最后一个模块,接下来的模块都属于存储引擎的范畴。所以,从上看,查询引擎最主要是构造SQL查询树、优化裁剪SQL查询树,根据查询树产生执行计划,然后协调执行查询树,把结果返回去。

  而真正要把数据取出来或存进去,就需要存储引擎来工作了。

  首先根据执行计划,要存取哪些数据页和索引页。这就是访问方法管理器(access methods manager)要做的事情。但其实真要打开这些页,还不是访问方法管理器自己要亲手干的。

  亲手干这个活的是一个叫“缓冲区管理器”的模块。因为在硬盘上的数据是不可能计算处理的,必须要在内存中才能让CPU来计算。所以要存取那些数据页和索引页,就通知让缓冲区管理器来做。如果数据没有在内存中,就让缓冲区管理器来读入,如果数据已经在内存中了,缓冲区管理器只有返回即可。这个过程是被缓冲区管理器来屏蔽的,对于访问方法管理器是透明的。大家可不要以为访问方法管理器啥事不做,只是一个发布调度命令的。这可错怪了它。因为SQLSERVER要保证高速处理,必须预先预测好哪些数据页和索引页要处理。不能人家缓冲管理器已经处理完,你访问方法管理器才计算下一步将要处理的页面。要知道,这些管理器可是不分哪个用户来处理的。如果接受来自100多个并发的用户,发来各种各样的数据处理请求,你怎么能预测到哪些数据页和索引页要处理呢?这就需要一个统一的调度。而且这个统一的调度也影响着缓冲区管理器。你不能请求一个大数据,缓冲区管理器这才火烧屁股才扩大缓冲区,然后装载数据,那样流水线就停下了。缓冲区管理器必须预先知道将在不久要有一个大数据,所以在并行运算的时候就有独立线程来扩展了缓冲区。因为扩大缓冲区还和操作系统有关。你要扩大缓冲区,正好遇到WINDOWS页面失效,就涉及到你的虚拟文件的变化。而页面失效又会影响CPU和I/O。所以页面失效是一个性能影响很大的问题。而提高命中率是我们性能优化一直努力的重点。如果数据长时间不用,缓冲区管理器就要让这块内存数据过期,可以被新的数据覆盖。否则缓冲区老加载不卸载也不行。再说,有些数据已经被更新了,你数据老化了,不重新读入,你的数据就引起读错误了。

  我们知道,数据页包含数据行。索引页包含索引行。数据行就由行管理器来控制。而索引行,由索引管理器来负责。

  而单行上的检索、修改、执行,又被事务管理器和锁管理器影响着。事务,有显性事务和隐性事务两种。而锁,又有共享锁、排它锁、更新锁、意向锁。而锁,还分为行锁、页锁、表锁、数据库锁。而锁,又有死锁的可能性。锁的不同,加上事务的影响,这个行是否能读、能修改,能怎样的读(读一致还是脏读),是等待事务和锁,还是可以进行,就受了很多影响。因为一张数据页上放的行是有限的,尤其还有填充度的影响(如填充度为80%,就这个数据页面只能填充80%就必须分页,以防以后有数据插入的时候,就非常影响数据插页,这也是性能影响比较大,尤其在插入数据比较多的情况下)。SQLSERVER的一张数据页默认是64K,除去填充度和数据头,也没有多少可存储的数据了。这就是为了关系型数据库都劝阻大家要小表大数据。也就是说,列要少,列要短,频繁访问的列要在前。数据可以海量。如果行长了,你想要检索和更新多少数据页,这需要多少页面调度,面临着页面失效和锁机制的影响。而且,大文本和可变行,都是指针存储,需要跳转查找,更浪费了不少时间。

  而索引管理器,最主要在维护着索引B树。没有索引页,我们就要做全表扫描了,那需要载入多少数据页,而且还要逐行扫描,如果遇上事务和更新锁,就更有问题。所以,索引是非常重要的。而一个表,可以建立很多索引。索引,能直接找到所需要的行,而无须全表扫描。但是,你的索引如果仅仅是男女,或者你的索引涉及到可变行,都对索引不利。索引,不宜建立多。否则维护索引页的成本和消耗也非常多。索引页更要涉及到插页、拆页,频繁改动涉及到索引的字段,会让索引页剧烈变动,尤其数据量越大影响越大。我就不在这里讲解如何利用索引优化SQL了,否则一本书也讲不完。

  数据不断存取,数据不断被维护,载入内存或从内存中写入硬盘。其实都是惰性写入器在照顾。惰性写入器来定期扫描老化数据,让硬盘和内存中的数据是一致的。有这个惰性写入器,就有了内存和硬盘的差异时间窗。就有可能出现异常。一旦服务器突然断电,没有来得及写会磁盘的怎么办。也也涉及到另一个模块:日志管理器。日志管理器利用检查点的机制维护着日志文件。在服务器重新启动的时候,重写载入日志来把数据恢复到一致性。写日志,当然要比写数据要容易的多,快的多。因为写数据要操控内存和硬盘,还要注意权限、锁、事务,所以突然断电,你还没反应就来不及了。所以日志这种轻量级的方法,就可以在恢复一致性上有很好的帮助(当然,也丢失数据。日志页也没来得及写入硬盘)。

  讲到这里,就剩下事务管理器、锁管理器。这两个管理器和显性事务、隐性事务、显性锁、隐性锁、事务隔离级别、锁级别、行管理器、索引管理器都有很多关系。微软有WINDOWS优势,又有Jim Gray这样的巨师坐镇(Jim Gray是图灵奖获得者,就是此爷提出了数据库事务这一概念。盖茨为了让此爷为微软工作,而此爷不喜欢雷德蒙天天下雨的天气,于是在加州阳光中给此爷单独建了一座研究院)。所以,在性能上,我个人认为SQLSERVER的性能是非常优秀的(你想想,一个数据库产品的性能受什么方面的影响)。至于业界老称SQLSERVER无法管理海量数据,性能不佳,我个人感觉都是业界在以讹传讹。而尤其中国内地IT业界,大部分都是入门级在跟帖嘈杂,尤其还有一批更不懂技术的媒体记者或写手。

  如果真要去说SQLSERVER不行,大型海量数据管理必须用某某数据库产品,我建议从内部原理、内部架构、内部实现三个层次诸多方面来剖析到底在不在理。

  最后就是I/O管理器了。我一直不认同SQLSERVER内核中有I/O管理器。因为SQLSERVER使用的是和WINDOWS同样的页面调度和页面分配方法。何必要自己另创一套呢。就如同SQLSERVER把页面、硬盘、内存、线程、CPU交给了WINDOWS一样。SQLSERVER作为WINDOWS上的一个应用软件,应该和WINDOWS上的其他软件一样被WINDOWS管理。SQLSERVER又不跨平台,无须自己管理。

  除了SQLSERVER这些内核涉及精妙以外,SQLSERVER的外围工具也设计的相当好。如SQLSERVER的用户安全性管理方法、对象分类(表、列、约束、默认、索引、触发器、存储过程、视图、主键)、对象权限方法、元数据自管理方法、SQL语言、SQL查询分析器、SQL跟踪器、SQL性能分析器、SQL数据库(master\msdb\tempdb\model)。

22/2<12
精选软件测试好文,快来阅读吧~

精彩评论

  • chech28
    2009-8-10 18:27:20

    一个小错误哈,1988年和sybase 合作的时候ms只是第二大软件公司

  • sunfly_3333
    2009-8-10 14:18:25

    原来一直停留在表面上的理解,今天的云里雾里,才让我对SQL有了别样的认识。感谢帖主流畅而通俗易懂的文字

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号