PG shared buffers的优化

本文很长,有8000字,建议大家先收藏再阅读。本文全面介绍了PG shared buffer pool的结构和一些常见的性能优化点和优化策略。在很多技术特征和概念上,与Oracle数据库做了一定的对比,可以让Oracle DBA通过参照更好的掌握PG的相关概念。

数据库的内存架构对数据库的性能影响十分大,PostgreSQL这些年的发展十分快,其内存架构的核心部分除了共享池外,都和Oracle有一定的类似。下图是PostgreSQL内存架构的一张逻辑示意图。这些结构中,shared memory对PostgreSQL数据库的性能影响很大。在PostgreSQL中最为重要的共享内内存缓冲包含Shared Buffer Pool,WAL Buffer和commit log。因为PostgreSQL数据库的SQL执行计划是会话级共享的,因此PostgreSQL数据库不需要类似Oracle的共享池结构。随着现代硬件技术的发展,CPU资源和内存资源都已经不会成为大型数据库的瓶颈了,因此SQL解析带来的开销已经不是系统中必须重点优化的工作了,反而是执行计划的效率更为重要,因此在现在的数据库产品中,全局共享CURSOR及其执行计划的设计逐渐不是主流了。

图 PostgreSQL逻辑架构图

本文我们重点讨论shared_buffers,这部分缓冲区对应于Oracle数据库就是db cache或者buffer cache。PostgreSQL的backend进程通过Buffer Manager模块来访问PostgreSQL的数据,而Buffer Manager通过Shared Buffer Pool来提高PostgreSQL数据访问的性能。backend访问PostgreSQL数据文件的过程和Oracle数据库十分类似,当backend要访问某个数据块的时候,会把需要访问的数据块的地址发送给Buffer Manager,如果这个数据块已经在Shared Buffer Pool中存在,那么Buffer Manager会返回包含这个数据的buffer id返回给backend,如果当前buffer中没有这个数据块,那么backend 通过调用Buffer Manager去申请一个buffer,然后把数据块的数据读入buffer,返回buffer id给后续处理使用。当然这是最简单的场景,对于分配buffer,还涉及了脏块的处理等过程,这里就不深入分析了,这些过程和Oracle数据库的DB CACHE是十分类似的,对Oracle数据库有所了解的DBA很容易理解这个过程。

为了实现这个过程,PostgreSQL的Buffer Manager分为三层:buffer table层、Buffer Descriptors层和buffer pool 层。buffer pool层是PostgreSQL buffer的物理实现,PostgreSQL的Buffer和Oracle一样,是一个固定长的数组,用于存放PostgreSQL的数据块。Buffer Descriptors层也是一个数组,是存储Buffer的元数据的层面,包含描述buffer及其状态的数据结构,此层的buffer描述和buffer pool中的数组是一一对应的。buffer table层是实现数据块寻址的,里面包含实现寻址的相关数据结构。整个体系如下图,这张图来自于著名的interdb.jp网站。

图1 PostgreSQL Buffer Manager

熟悉Oracle Buffer CACHE的人可能比较容易理解这个过程,在Oracle中也是Buffer HEAD(具体可参考X$BH)指向具体的Buffer,而通过HASH CHAINS来实现数据块的寻址。

PostgreSQL的数据块寻址也是通过HASH CHAINS的,这一点与Oracle类似。了解Oracle的DBA应该很容易回忆起Oracle是通过一个32位的rdba来实现Buffer定位的,其中10位是FILEID,22位是BLOCKID(BIGFILE TABLESPACE是32位的BLOCKID)。PostgreSQL这方面复杂一些,是通过一个叫做buftag的数据结构来唯一定位某个数据块的。

图2 buftag数据结构

buftag包含三个字段,rnode是一个RelFileNode的数据结构,包含了数据对象的inode信息;ForkNumber 为0表示该块是表或者索引文件的数据文件,1表示是freespace map的数据,也就是对应的_fsm文件,2表示是visibility maps的数据,对应的是_vm文件。BlockNumber是数据块的块号。因为PostgreSQL的表空间结构和Oracle不同,所以PostgreSQL的数据与具体文件的对应关系相对复杂一些,因此因为无法像Oracle一样用一个32位的数值+一个表空间ID就能表示某个数据块的物理位置,这样会浪费一些内存空间,不过对于内存价格已经比较低的现在,内存已经完全不是问题了。

和Oracle的RDBA一样,PostgreSQL的buftag能够唯一定位某个数据块的位置。通过Hash算法对buftag计算HASH值就可以获得这个buffer descriptor的hash bucket的桶号。

uint32 bucket_slot = calc_bucket(unsigned hash(BufferTag buffer_tag), uint32 bucket_size)

所有的已经装在到Buffer中的数据块缓冲都被链接在HASH桶中,每个BUCKET上都有一个链表,链接了该桶中的所有Buffer。因为无论HASH BUCKET的数量有多大(比如超过Buffer 的数量),也无法排除在一个BUCKET中可能会链接多个Buffer。这一点也是和Oracle的HASH CHAINS类似的。

图3 Shared Buffers初始化状态图

上图是Shared Buffers pool刚刚初始化的示意图,此时hash table上都是空的,同时所有的buffer descritors都被链接在freelist上,而且没有连接任何buffer。

图4 准备载入一页数据

第一个数据块访问请求提交给Buffer Manager的时候,首先通过buftag算出hash bucket的位置,在hash bucket上看到是空的,于是从freelist分配一个buffer descriptor。然后从数据文件中读取该数据,放入这个buffer descriptor对应的buffer 中。

图5读入数据

此时,Buffer中就缓冲了这个数据块了,下回再访问这个数据块,就可以通过buftag直接定位到hash bucket,从而找到这个buffer了。

上面的示意图都来自于Hironobu SUZUKI的原创,以上的算法描述也基本上基于Hironobu SUZUKI大师的资料。从一个DBA的角度来看PostgreSQL的Buffer Manager,看到了一个和Oracle类似的Buffer Cache的算法。因此在PostgreSQL数据库中,也会存在类似于Oracle db cache带来的一些并发争用问题,比如cache buffer chains闩锁等待,buffer busy wait等待等问题。

类似Oracle cbc闩锁的是一种PostgreSQL的轻量级锁lwlock,这个锁的名字在PostgreSQL的各个版本中可能有所不同,我们统一称之为buffer_mapping(BufMappingLock),这个轻量级锁用于HASH TABLE的串行化访问。因为在每个buffer 访问中都需要使用这个锁,因此和Oracle一样,PostgreSQL采用了分区锁的方式,将整个HASH TABLE分为多个分区(缺省为128个,不同版本缺省值会有不同),每个分区使用一个lwlock来管理。

图6 Buffer访问的串行化控制

当有多个backend来访问buffer cache的时候,首先通过计算HASH值,找到HASH TABLE的位置,然后获得相关的BufMappingLock,才能去访问HASH TABLE,找到HASH CHAIN,最终找到对应的Buffer。当两个BACKEND访问的Buffer属于不同的分区锁控制的时候,不会产生冲突,反之就会产生冲突。前阵子我们在对瀚高数据库做压测的时候,也观察到了这个轻量级锁的冲突:

图7 Buffer_mapping等待统计

在11分钟的压测中,产生了110秒的BufMappingLock等待,占整个等待的0.255%,看上去PostgreSQL的BufferManager的效率还是很高的,在每秒钟超过476万次的buffer 访问中,这个锁的等待只有110秒,平均每次等待为0.023毫秒,这个效率已经相当不错了。从这里可以推断,在实际生产环境中,PostgreSQL因为BufMappingLock导致的热块冲突控制还是相当不错的。

在Buffer Descriptor层,每个buffer_id有两个轻量级锁,content_lock 和 io_in_progress_lock,这里和Oracle是有些区别的,不过从原理上也十分类似。对应于Oracle的等待,等待这两个lwlock的等待类似于buffer busy waits和read by another session这两种等待。实际上在Oracle数据库里,Oracle 10g之前是对buffer busy waits分为几种类别,但是统一使用这个等待事件,Read by other session这个等待是buffer busy waits中的一个特例,就是说某个会话等待访问某个buffer的时候,这个buffer 的buffer descriptor已经产生,buffer pool也已经分配了空间,只是这个bufffer中的数据正由另外一个backend从数据文件中读取到buffer中,这个读取的IO还没有完成。PostgreSQL的io_in_progress_lock是和Oracle的这个等待完全类似的,也许是PostgreSQL借鉴了Oracle的思想。我们再回过头来看上面的那个图中的buffer_content等待和buffer_io等待,对应的就是content_lock 和 io_in_progress_lock这两个lwlock的等待时间,可以看出,buffer_content等待大约是322秒,根据BufMappingLock等待估算一下,大约平均每次等待也只有0.06毫秒左右,效率还是比较高的。在分析PostgreSQL数据库的Buffer层面的冲突导致的性能问题的时候,我们可以根据这三个等待的数量与耗时方面的不同比例关系来判断问题可能会出在什么地方。

图8 分析Buffer相关等待的原因

如果buffer_io的等待比较多,那么很可能问题出在IO层面,或者IO延时过大,或者物理IO的数量过多,如果buffer_content的比例比较多,那么说明并发访问热块冲突比较严重。

PostgreSQL的Shared Buffers和Oracle的DB CACHE十分相似,事实上,一个Oracle DBA往往会用错误的方式来看待PostgreSQL的Shared Buffers。为什么呢?这和Oracle与PostgreSQL的数据库的存储结构方面存在的差异有关。

Oracle数据库的数据库物理结构是基于表空间与数据文件这个基础架构的。PostgreSQL也有表空间,也是和Oracle类似,表空间是一个逻辑概念。不过Oracle的数据文件结构是和PostgreSQL完全不同的。Oracle的数据文件是预分配的,确定的,在操作系统中,数据文件的每个块的地址都是已知的。因此Oracle能够更加自主的控制对物理文件上的数据的读写,利用DB CACHE和预读机制来减少IO。早期的Oracle DBA都会有这个感受,使用了裸设备之后,比使用文件系统,IO总体性能会有一定的提升,这个提升幅度在5%左右。从使用裸设备比使用文件系统总体IO性能有所提升可以看出,Oracle 的DB CACHE+预读机制基本上可以替代文件系统缓冲,因此Oracle数据库不需要使用过多的操作系统缓冲(不是完全不使用,而是不需要过多使用,实际上文件系统缓冲对于Oracle提升文件系统的读IO还是有帮助的,甚至对于裸设备,裸设备的块设备缓冲对IO性能也是有提升的,最为典型的就是AIX系统的PBUF)。

而PostgreSQL则不同了,PostgreSQL的数据物理存储结构是按文件的,每个表对应的是几个数据文件,因此所有的文件IO加速机制都是和表相关的,不能使用像Oracle表空间一样的预读机制。PostgreSQL如果要做预读,不同的业务负载下,预读缓冲的效率会有巨大的不同。因此对于文件系统的IO优化,PostgreSQL更多的是交给操作系统来做的。因此,操作系统的文件缓冲与虚拟内存的配置会对PostgreSQL数据库的性能有着十分重要的影响。

另外由于PostgreSQL独特的MVCC机制,或导致对某一条记录的修改并不是在原来的位置上修改,因此Shared Buffers中数据块的一次读入,多次访问的特性会比Oracle数据库打一些折扣,也就是说PostgreSQL的Shared Buffer Pool在这方面的效率会略微低一点。

基于这个特点,实际上PostgreSQL数据库在配置Shared Buffer Pool的时候,就不能参考Oracle的经验了。PostgreSQL的官方文档建议把Shared Buffer Pool设置为整个屋内内存的15-25%,对于一个32G以上的数据库服务器,建议的Shared Buffer Pool的大小是8GB。目前64G甚至更大内存的服务器都已经十分普及了,因此这个官方文档所建议的8GB的设置建议偏保守了一点,另外针对不同的应用场景,PostgreSQL的Shared Buffers的配置策略并不是这么僵化的。PostgreSQL的官方配置对于一个初级的DBA来说可以确保PostgreSQL数据库不会因为错误的内存配置而出现严重的问题。而对于一个高级PostgreSQL DBA来说,我们需要更为精准的配置方案。要想更好的优化好数据库缓冲区,我们需要首先来了解一下PostgreSQL的double buffering问题。

对于以往习惯于使用Oracle数据库的人来说,不会体会到Double Buffering这个词的含义。很多Oracle DBA也认为Oracle天生就不需要考虑Double Buffering的问题的,只有PostgreSQL/MYSQL这样的开源数据库才需要关心。事实上,Oracle也就是最近这十几年才彻底的解决了Double Buffering问题,采用完全绕过文件缓冲区的方法的,在我早期使用的Oracle版本中,如何利用文件缓冲提升大数据量的访问性能还是Oracle DBA能够用来挣钱的独门绝技,我也曾利用这个技能帮助用户做过一些优化项目。既然今天要讨论Double Buffering,那么我们就先用PostgreSQL的一个IO分层结构图来理解一下PostgreSQL的这个问题吧。

图9 Double Buffering示意图

我们看到最上面的shared buffer是PostgreSQL的主Buffer,PostgreSQL数据库使用Buffered IO和操作系统文件系统进行交互,因此PostgreSQL数据库的读写都需要使用OS CACHE作为缓冲,读取的数据可以通过OS CACHE来进行加速,写入的数据先写入OS CACHE中,然后再通过fsync()来强制刷盘。在PostgreSQL数据库里,我们要访问一个数据块可能会经过两个CACHE,一个是PostgreSQL自己的Shared Buffers,一个是操作系统的CACHE(文件缓冲),这就是Double Buffering的含义。

Double Buffering有什么缺点呢?首先是增加了一个数据块访问的路径,数据块要先读入OS CACHE,然后才能到达Shared Buffers,而这个PAGE在Shared Buffers中被多次使用,期间不再需要再次从文件中读取,因此OS CACHE中的缓冲的效率其实并不高,甚至可能会产生负面的作用。对于PAGE的写入也是如此,你不知道PAGE是写入文件了还是仍然存在于OS CACHE中,有时候我们必须通过fsync()来强制同步OS CACHE与文件系统。这种Double Buffering确实增加了PostgreSQL数据库在cache管理上的复杂性。

实际上,PostgreSQL数据库是能从OS CACHE上大大受益的。首先无论是Oracle的DB CACHE还是PostgreSQL的Shared Buffer Pool,其目的不外乎几个。第一,减少数据库服务器的物理IO,从而提升数据库的整体效率,减少物理IO的工作大部分可以由Shared Buffer Pool buffers来做;第二,缓冲数据,削峰填谷,和系统中所有环节上的CACHE一样,OS CACHE也可以削平OS上的大流量IO,从而让系统处于较为平稳的运行状态。

和数据库的缓冲区不同的是,操作系统的CACHE是一种管理更为简单的,更为灵活的缓冲系统,不过文件缓冲对于数据块IO的减少,并不够专业。操作系统缓冲并不从数据库的角度去缓冲数据,而是通过预读等机制来优化文件系统的IO性能。而Shared Buffer Pool是和数据库的一致性访问紧密相关的缓冲区,里面存储的都是数据库使用的数据块,对Shared Buffer Pool的访问都必须通过lwlock来进行并发控制,其访问成本相对较高。因此,通过Shared Buffer Pool和操作系统缓冲之间的访问量的平衡,可以更好的控制数据库访问数据的性能。通过这种Double Buffering的机制,可以在各种复杂的应用负载下,都能够找到一个平衡的配置,从而让缓冲区的效率达到最佳。

图10 Backend命中方式示意图

当Backend要读取数据的时候,首先要通过lwlock去锁定相关的内存结构,然后对Shared Buffer Pool进行一致性读取,如果找到了,那么就产生了一个逻辑读;如果没有找到,那么就会产生一个“逻辑物理读”操作,去操作系统中读取这个数据。这里我用了一个“逻辑物理读”这个十分别扭的词汇,是因为这个物理读有可能并没有产生真正的物理读,而只是从操作系统缓冲中读取到了这部分数据,实际上并没有产生物理IO;如果在OS CACHE里还是没有找到,那么就要产生实际的物理读了,从数据文件中把数据块读入OS CACHE和Shared Buffer Pool。

第三种方式是成本最高的,其次是方式二,访问成本最低的是方式一。因此无论是什么样的数据块系统,最好都通过第一种方式来获取数据。把Shared  Buffer Pool的命中率提高到最高,就能让绝大多数的访问都是使用方式一的。对于Oracle数据库来说,因为Oracle使用了表空间这种文件存储结构,文件空间的地址相对固定,因此只要DB CACHE的大小足够大,那么一个数据块被读取到DB CACHE中之后,会被更长时间的保存在DB CACHE里,被多次访问。标中新写入的数据或者UPDATE一条数据,也是尽可能先写入已经放在DB CACHE的块中,或者直接在DB CACHE中修改。

PostgreSQL数据库的物理存储架构与Oracle大不相同,表数据是存储在独立文件中的,建立一张新的表,就会创建一个新的文件,修改一条数据,也不会在原来的记录上修改,而是会新产生一条记录,这条记录很可能会写在一个不同的块中。因此一个数据块存储到Shared Buffer Pool中之后,很可能多次被访问的几率没有Oracle高,这样Shared Buffer Pool的效率就有可能在某些应用场景下没有Oracle DB CACHE这么高了。因此,针对某些数据重用率不高的应用,Shared Buffer Pool设置的太大,反而会挤占OS CACHE的容量,从而让数据库的整体性能变得更差。而实际上,如果我们的应用是能够很好的多次访问相同的数据的情况下,比如写入操作比较少,读操作比例比较高的数据库中,设置一个较大的shared buffers,让逻辑读的比例提高,肯定是能够获得较好的性能的。

另外一方面针对写IO,写入OS CACHE的延时要远远低于直接写入文件系统。而对于一些访问十分频繁的热表,OS CACHE也是能够明显的提升IO性能的。而交给DBA的最为主要的问题是,我们如何管理好这个Double Buffering的环境。

这种管理确实比Oracle这样的使用O_DIRECT访问的数据库要复杂的多,在Oracle数据库管理方面,我们只需要设置一个足够大的sga_target甚至Memory_target基本上就万事大吉了。而在PostgreSQL数据库的缓冲区管理中,我们还必须考虑如何平衡Shared Buffers和OS CACHE。在PostgreSQL的官方文档中,建议PostgreSQL数据库的Shared Buffers设置为物理内存的25%左右而不要设置的过高,这个建议主要还是为了平衡OS CACHE和Shared Buffers,让OS CACHE和Shared Buffers同时作为缓冲来使用,虽然Shared Buffers作为数据库主缓冲,其实其对IO的优化作用不见得比OS CACHE高多少。对于一些不是很大的PostgreSQL数据库,特别是服务器的内存不是很大的数据库系统来说,这是一个较为稳妥的设置方案。可以充分利用OS CACHE,并且避免OS 换页带来的更大的性能问题。因此也有很多PostgreSQL DBA认为Shared Buffers不宜设置过大,过大的Shared Buffers对PostgreSQL数据库性能提升没有多大帮助。不过有很多用户用自身的体验驳斥了这种观点。通过加大Shared Buffers,提高Cache Buffer的命中率,获得了较好的数据库性能。有的DBA把超过75%的物理内存使用到Shared Buffers上,也获得了良好的使用效果。这种模式实际上是把Shared Buffers作为主缓冲,OS CACHE作为副缓冲。对于大部分PAGE被读入Shared Buffer Pool后都会被很好的多次访问的情况下,把更多的内存配置到Shared Buffer Pool上,可能会获得更好的效果。

实际上对于PostgreSQL的Double Buffering,网上的很多观点都有些偏颇,可能持这些观点的人面对的都是自己的系统,并没有关注过不同负载的数据库的需求。因此如果从一个较为全面的角度来说,在现阶段,PostgreSQL内核还要依赖于OS CACHE来提升PostgreSQL性能的前提下,Double Buffering依然是目前我们无法绕过去的问题。而对于大多数小系统来说,Double Buffering并不会给我们带来太大的烦恼,只要确保OS不换页,Doube Buffering的副作用是有限的,我们甚至可以完全忽视的。而对于大系统来说,设置多大的Sahred Buffers是我们需要去面对的头疼的问题,因为面对不同的应用负载,不同的个性化的系统,需要采用不同对的设置策略来合理配置Shared Buffer Pool,并且定期对系统的性能进行评估,做出调整。不像我们在管理Oracle数据库那样,只需要确保物理内存足够,OS不换页的情况下,尽可能提高DB CACHE的命中率就可以了。

在PostgreSQL数据库中,90%的db cache命中率不一定比80%的db cache命中率有更好的运行性能,因为有可能有我们看到的90%的物理IO实际上是从OS CACHE中读取数据的。基于Double Buffering的问题,DBA需要根据自己维护的数据库系统,通过个性化的优化策略来评估DB CACHE和OS CACHE对系统带来的性能提升,才能更加正确的设置相关参数,让数据库体验的效果更好。对于大型的PostgreSQL数据库系统,这一点尤为重要。

实际上这对于DBA来说是一个福音,问题出现了,特别是不容易解决的问题出现了,那么体现DBA价值的机会就来了。实际上,解决PostgreSQL数据库的Double Buffering问题也并不是像想象的那么困难。注意好几点,大部分系统的这个问题都可以得以解决。首先,不要相信只能使用25%物理内存作为Shared Buffers这种固化的经验,因为每个系统都是个性化的,提高Shared Buffer Pool的命中率在绝大多数场景下都是有价值的。其次,需要针对操作系统的VM参数做更为精细的调整,包括脏块刷新的策略,这方面在操作系统优化的章节里就有很详细的介绍,这里就不重复讨论了,有兴趣的朋友可以去读读相关的章节。

针对Double Buffering的问题,我们来画一下重点。首先,PostgreSQL的Shared Buffer Pool和OS CACHE共同发挥作用,可以让数据库有效的减少物理IO,提升数据库的总体性能;其次,Shared Buffer Pool的设置并不是越大越好,Shared Buffer Pool的命中率也没有Oracle DB CACHE命中率那么有指向性,没有命中的PAGE也可能不需要物理读,可以直接从OS CACHE中读取到;第三,通过对应用系统的访问特性的分析,根据数据页在Shared Buffer Pool中可能被多次访问的比例,以及这部分数据的大小,可以大致确定Shared Buffer Pool的合理配置,同时根据应用的访问特性,可以大致确定OS CACHE与Shared Buffer Pool的比例;第四,根据服务器的IO能力和数据库的IO访问流量,通过调整OS层面的脏页写入策略参数和PostgreSQL数据库的Checkpoint相关参数,可以获得一个较匹配的配置,增加系统的IO总吞吐量,降低平均IO延时,这对于大系统上做PostgreSQL优化十分重要。

最后,PostgreSQL数据库实际上有很多解决这方面问题的插件,可以帮助我们提升OS CACHE的效率,比如针对性的进行OS CACHE/Shared Buffers的预热等,在某些比较大型的数据库系统,比较复杂的应用场景下,这种预热十分有效。有兴趣的朋友可以去研究一下PostgreSQL fincore这个开源插件,应该会有一些收获的。

除了设置数据库缓冲区的大小之外,另外还有一点需要注意的是,对于大内存的服务器,HUGEPAGE也是必须要注意的,HUGEPAGE同样能够给PostgreSQL数据库带来性能上的提升。Shared Buffer Pool使用HUGEPAGE的方法与Oracle类似,透明大页能给Oracle带来的负面影响,对PostgreSQL也同样成立。

刚才我们讨论过,对于PostgreSQL数据库IO性能影响最大的还有另外一个因素,就是操作系统的文件缓冲。对PostgreSQL数据库来说,最佳的模式是将50%的物理内存用于文件系统缓冲。对于某些小型机操作系统,比如AIX,HP-UX,可以通过操作系统的参数比较精准的控制文件系统缓冲的大小。而对于LINUX操作系统,这是十分复杂的,我们需要通过一系列的VM参数来进行综合调整,大体控制文件系统缓冲的大小。不幸的是,我们目前绝大多数PostgreSQL都是跑在LINUX上。对于如何通过VM参数的调整来让PostgreSQL能够在最优化的文件系统缓冲上跑是个十分复杂的问题,甚至50%的比例也不一定是最佳的,我最近在REDDIT上看过一些老外的研讨,最终结论也是不确定的。不过有一点是明确的,那就是无论如何,尽可能不要产生较大的换页,产生较大的换页,可能会导致PostgreSQL总体性能的不稳定。

最后我们必须来聊聊预制相关的EFFECTIVE_CACHE_SIZE参数,许多PostgreSQL用户可能对这个参数比较迷惑。有些用户把这个参数看成是PostgreSQL使用文件系统缓冲的大小,这其实是一个误解。在LINUX中,如何有效的控制文件系统缓冲的大小是十分困难的。实际上这个参数只是一个用于CBO优化器估算成本使用的参数,而不是实际上PostgreSQL使用文件系统缓冲的大小。这个参数的默认值是OS内存的50%,从这里也可以看出,PostgreSQL希望能够使用50%的物理内存作为文件系统缓冲,从而优化IO。这个参数对于索引扫描的成本估算十分关键,如果这个参数设置的较大,则在CBO优化器中,计算出来的索引扫描的成本也就越低。

  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值