在Sqlserver中,数据的交互实际上是一种磁盘活动,即是一种IO操作。然而,为了加快读取速度,减低CUP负荷,Sqlserver会将许多的数据预先加载进入内存中,程序所进行的数据交互,优先在内存中进行。因此,SqlServer占用了很多的内存。只要访问的数据还在内存中,就不需要磁盘IO来读写存储在缓冲中的数据值。如果没有足够的内存来存储经常用到的数据,就意味着数据必须在内存和磁盘自检不断地来回移动。尽管交换在SqlServer中很常见,但是它非常消耗时间和性能,所以要尽可能地减少这样的活动。
在软件开发中,使用了ORM映射工具的系统,如C#的Linq和JAVA中的Hibernate,进行数据交互,都会占用大量的数据库内存,因此,采用了这一类映射工具的系统,往往都会遇到SqlServer内存瓶颈问题,2GB对于这样的系统来说,简直太少了。而且,多个数据库实例运行在一台服务器上的时候,很容易造成数据库实例为了争抢内存而发生饿死现象。
那么SqlServer在实际中可以用到多少内存,又怎么样最大化利用系统内存呢?
影响到SqlServer可使用内存的因素很多,主要有服务器的CPU体系结构和SqlServer的版本。本文将以32位操作系统为例,讲解如果最大化利用系统内存为SqlServer服务。
32位的环境中,SqlServer的物理可寻址内存限制在2GB以内,由于32位操作系统体系结果的限制,操作系统可寻址内存总共只有4GB,2GB是操作系统专用,2GB可以供给SqlServer使用。这样就限制了SqlServer的内存利用率。
解决方案之一:在Windows Server 2003以及更高的版本中,它们全面支持一个叫做/3GB的开关。
可以把/3GB开关加入到boot.ini文件中的(我的Win7系统中没有找到,XP据说在C盘根目录下),这样操作系统就可以只使用1GB,SqlServer使用3GB。
解决方案之二:使用boot.ini的文件中的/PAE开关。这个开关控制了物理地址扩展(Physical Address Extensions,PAE),允许多个应用程序使用超过4GB的内存,在屋里地址可用的情况下,每一个SqlServer实例都会得到自己的2GB内存块,而不会与其他SqlServer实例竞争内存资源,如果与/3GB开关同时使用,则可以让每一个实例都得到自己的3GB物理内存。
注:这两个开关同时开启时,当计算机有超过16GB内存,服务器将不能访问16GB以外的内存,因为这时候操作系统需要2GB的内存来寻址16GB以外的内存。
解决方案之三:使用SqlServer中的地址窗口扩展(Address Windowing Extension,AWE),这个选项可以显著增加SqlServer实例的可访问扩展内存。Win2003的版本在AWE下可以用4GB内存,win2003企业版支持高达32GB应用程序内存。需要在SqlServer属性中勾选上AWE。使用这个选项必须设置“内存策略”中的“锁定页面”来阻止扩展内存被分页存储到磁盘。还需要考虑将SqlServer选项“最大服务器内存”设置为一个合适的值。如果多个是咧运行的话,这样可以防止所有实例的最大服务器内存值的总和不超过可用于应用程序的物理内存。
64位操作系统配置更简单,内存更大化(可以达到8TB),
行业的趋向是,采用64位机器。将来系统扩大时,可以利用该平台的可扩展性。
更多细节内容可以通过查阅联机丛书获得。
本文参考《精通SqlServer2008》 清华大学出版社出版。