SQLServer占用的内存主要由三部分组成:数据缓存(DataBuffer)、执行缓存(ProcedureCache)、以及SQLServer引擎程序。SQLServer引擎程序所占用缓存一般相对变化不大,则我们进行内存调优的主要着眼点在数据缓存和执行缓存的控制上。
SQL语句在执行前首先将被编译并通过查询优化引擎进行优化,从而得到优化后的执行计划,然后按照执行计划被执行。对于整体相似、仅仅是参数不同的SQL语句,SQLServer可以重用执行计划。但对于不同的SQL语句,SQLServer并不能重复使用以前的执行计划,而是需要重新编译出一个新的执行计划。同时,SQLServer在内存足够使用的情况下,此时并不主动清除以前保存的查询计划。这样,不同的SQL语句执行方式,就将会大大影响SQLServer中存储的查询计划数目。如果限定了SQLServer最大可用内存,则过多无用的执行计划占用,将导致SQLServer可用内存减少,从而在执行查询时尤其是大的查询时与磁盘发生更多的内存页交换。如果没有限定最大可用内存,则SQLServer由于可用内存减少,从而会占用更多内存。
我们都知道 MySQL 的 Table Cache 是表定义的缓存,江湖上流传着各种对这个参数的调优方法。table cache 的作用,就是节约读取表结构文件的开销。对于table cache 是否命中,其实table cache 是针对于线程的,每个线程有自己的缓存,只缓存本线程的表结构定义。不过我们发现,strace 中没有关于表结构文件的 open *** 作(只有 stat *** 作,定位表结构文件是否存在),也就是说 table cache 不命中,不一定需要读取表结构文件。这种感觉好像是:在不命中 table cache 时,命中了另外一个表结构缓存。
运维建议:
我们读一下 MySQL 的文档,关于 table_open_cache 的建议值公式:建议值 = 最大并发数 * join 语句涉及的表的最大个数。
通过实验我们容易理解:table_cache 是针对于线程的,所以需要最大并发数个缓存。另外,一个语句 join 涉及的表,需要同时在缓存中存在。所以最小的缓存大小,等于语句 join 涉及的表的最大个数。将这两个数相乘,就得到了 MySQL 的建议值公式。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)