postgresql-effective_cache_size参数详解

在 PostgreSQL 中,effective_cache_size 是一个配置参数,用于告诉查询规划器关于系统中可用缓存的估计信息。这个参数并不表示实际的内存量,而是用于告诉 PostgreSQL 查询规划器系统中可用的磁盘缓存和操作系统级别的文件系统缓存的大小。它用于帮助 PostgreSQL 优化器估计特定查询所需的成本,以选择最佳的查询计划。

effective_cache_size 参数的设置可以在 PostgreSQL 的配置文件 (postgresql.conf) 中进行,也可以使用 ALTER SYSTEM 命令在运行时动态修改,但需要重新加载 PostgreSQL 的配置以使更改生效。

这个参数的值通常设置为系统可用缓存的大致大小。一般情况下,你可以设置为系统可用内存的一部分,但不要超过系统实际可用内存的大小。

例如:

effective_cache_size = 4GB

这个设置表示 PostgreSQL 会假设系统中大约有 4GB 的缓存可用于数据块的读取。这个值的设置可以因系统的实际硬件和负载情况而异,需要进行一些试验和性能测试来确定最佳的值。

调整 effective_cache_size 可以影响查询优化器对索引扫描、排序和连接等操作的成本估计,进而影响 PostgreSQL 执行计划的选择。

记住,修改这些参数时最好在测试环境中进行,并且需要仔细监控系统的性能变化,以确定最佳的设置。

这个参数主要用于Postgre查询优化器。是单个查询可用的磁盘高速缓存的有效大小的一个假设,是一个估算值,它并不占据系统内存。由于优化器需要进行估算成本,较高的值更有可能使用索引扫描,较低的值则有可能使用顺序扫描。一般这个值设置为内存的1/2是正常保守的设置,设置为内存的3/4是比较推荐的值。通过free命令查看操作系统的统计信息,您可能会更好的估算该值。

调整effective_cache_size参数可以控制Postgresql必须在buffer cache中提取查询数据的频率,从而提升查询性能。

1. 案例一

以下转载自:本文来自博客园,作者:[abce](https://www.cnblogs.com/abclife/),转载请注明原文链接:[https://www.cnblogs.com/abclife/p/14565691.html](https://www.cnblogs.com/abclife/p/14565691.html)

优化器假设可以用于单个查询的磁盘缓存的有效大小。这个因素会被用到使用索引的成本考虑中:值越大,使用索引扫描的可能性就越大;值越小,使用顺序扫描的可能性就越大。
设置该参数的时候,需要同时考虑到shared buffer和内核对磁盘缓存的使用,尽管有些数据会同时存在shared buffer和内核的磁盘缓存中。同时要考虑到在不同的表上并发查询的数量,因为他们也会使用到共享空间。
该参数不会影响分配给postgresql的共享内存,也不保留内核磁盘缓存。只是用于优化器的评估目的。系统也不会假设不同查询之间的数据保留在磁盘缓存上。默认是4GB。

指定值的时候,如果不指定unit,默认就是block。

select name, setting, unit from pg_settings where name like 'effective_cache_size';
namesettingunit
effective_cache_size5242888kB

成本评估要考虑很多因素:i/o数量、操作调用次数、处理的元组的数量、选择性等等。但是i/o的成本是什么呢?很显然,如果数据已经在cache中或数据在磁盘上,代价显然是不同的。

参数effective_cache_size就是用来告诉优化器,系统可以提供多大的cache。这里的cache不仅仅是内存的cache,也考虑了文件系统cache、cpu的cache等。effective_cache_size是这些cache的总和。

postgres=# create table t_random as select id,random() as r from generate_series(1,1000000) as id order by random();
SELECT 1000000postgres=# create table t_ordered as select id,random() as r from generate_series(1,1000000) AS id;
SELECT 1000000postgres=# create index idx_random on t_random(id);
CREATE INDEXpostgres=# create index idx_ordered on t_ordered(id);
CREATE INDEXpostgres=# vacuum analyze t_random;
VACUUMpostgres=# vacuum analyze t_ordered;
VACUUMpostgres=#

两个表都包含相同的数据,一个表是有序的,一个是无序的。

将effective_cache_size设置一个较小的值。优化器会认为系统的内存不是很多:

postgres=# set effective_cache_size to '1 MB';
SETpostgres=# show effective_cache_size;effective_cache_size
----------------------1MB
(1 row)postgres=# set enable_bitmapscan to on;
SETpostgres=# explain SELECT * FROM t_random WHERE id < 1000;QUERY PLAN                                
----------------------------------------------------------------------------Bitmap Heap Scan on t_random  (cost=19.71..2453.44 rows=940 width=12)Recheck Cond: (id < 1000)->  Bitmap Index Scan on idx_random  (cost=0.00..19.48 rows=940 width=0)Index Cond: (id < 1000)
(4 rows)postgres=# set enable_bitmapscan to off;
SETpostgres=# explain SELECT * FROM t_random WHERE id < 1000;QUERY PLAN                                   
---------------------------------------------------------------------------------Index Scan using idx_random on t_random  (cost=0.42..3732.86 rows=940 width=12)Index Cond: (id < 1000)
(2 rows)postgres=#

通常pg会走bitmap索引扫描,但是这里我们想看看索引扫描会发生什么。所以关闭了bitmap索引扫描。

postgres=# SET effective_cache_size TO '1000 GB';
SETpostgres=# explain SELECT * FROM t_random WHERE id < 1000;QUERY PLAN                                   
---------------------------------------------------------------------------------Index Scan using idx_random on t_random  (cost=0.42..3488.86 rows=940 width=12)Index Cond: (id < 1000)
(2 rows)postgres=#

可以看到,索引扫描的成本降低了。

我们必须把成本看作是“相对的”。绝对的数字并不重要——重要的是一个计划与其他计划相比有多贵。
如果顺序扫描的成本保持不变,而索引扫描的价格相对于顺序扫描下降了,PostgreSQL会更倾向于索引。这正是effective_cache_size的核心内容:在有大量RAM的情况下,更有可能进行使用索引扫描。

当谈及如何配置postgres.conf文件中的effective_cache_size的设置的时候,往往没有意识到并不会有什么神奇的效果。

postgres=# set effective_cache_size to '1 MB';
SET
postgres=# explain SELECT * FROM t_ordered WHERE id < 1000;QUERY PLAN                                   
---------------------------------------------------------------------------------Index Scan using idx_ordered on t_ordered  (cost=0.42..38.85 rows=996 width=12)Index Cond: (id < 1000)
(2 rows)postgres=# SET effective_cache_size TO '1000 GB';
SET
postgres=# explain SELECT * FROM t_ordered WHERE id < 1000;QUERY PLAN                                   
---------------------------------------------------------------------------------Index Scan using idx_ordered on t_ordered  (cost=0.42..38.85 rows=996 width=12)Index Cond: (id < 1000)
(2 rows)postgres=#

优化器使用的表统计信息包含关于物理“相关性”的信息。如果相关性是1,即所有数据是有序的在磁盘上。effective_cache_size并不会改变什么。

如果只有一个列,同样也不会有什么效果:

postgres=# ALTER TABLE t_random DROP COLUMN r;
ALTER TABLE
postgres=# SET effective_cache_size TO '1 MB';
SET
postgres=# explain SELECT * FROM t_random WHERE id < 1000;QUERY PLAN                                    
-----------------------------------------------------------------------------------Index Only Scan using idx_random on t_random  (cost=0.42..28.88 rows=940 width=4)Index Cond: (id < 1000)
(2 rows)postgres=# SET effective_cache_size TO '1000 GB';
SET
postgres=# explain SELECT * FROM t_random WHERE id < 1000;QUERY PLAN                                    
-----------------------------------------------------------------------------------Index Only Scan using idx_random on t_random  (cost=0.42..28.88 rows=940 width=4)Index Cond: (id < 1000)
(2 rows)postgres=#

调优建议:

effective_cache_size = RAM * 0.7

如果是pg专用服务器,也可以考虑设置为RAM*0.8。

2. 案例二

effective_cache_size 是一个用于告诉 PostgreSQL 查询规划器关于系统中可用缓存的估计信息的配置参数。它的设置影响着 PostgreSQL 查询优化器对于不同查询计划的成本估算,从而影响了 PostgreSQL 查询优化器选择最佳执行计划的方式。

下面是一个使用 effective_cache_size 参数的案例:

假设你有一个数据库,其中包含大量的表和数据。在某次查询中,你需要从一个包含大量数据的表中检索信息,比如一个产品销售表。

SELECT * FROM sales_data WHERE product_id = 'XYZ';

在没有充足的缓存情况下,数据库可能需要频繁地从磁盘读取数据块以满足查询需求,这会增加查询的执行时间。

通过配置 effective_cache_size 参数,你可以告诉 PostgreSQL 查询优化器关于系统中可用缓存的估计信息,从而影响查询优化器的成本估算,这可能导致选择不同的查询执行计划。

假设你的系统有足够的内存,并且已经对 effective_cache_size 进行了适当的设置,PostgreSQL 查询优化器会认为系统中有更多的缓存可用。在这种情况下,它可能更倾向于选择全表扫描而不是索引扫描,因为它认为大部分数据已经在缓存中,并且全表扫描可能更快。

然而,如果 effective_cache_size 设置得太小,查询优化器会认为系统中的缓存较少,可能会倾向于选择索引扫描,因为它认为从磁盘中读取少量数据会更快。

因此,effective_cache_size 参数的调整会影响查询执行计划的选择。合理设置这个参数可以帮助 PostgreSQL 优化器更准确地估计查询成本,选择更有效的执行计划,提高查询性能。

需要注意的是,这个参数的最佳设置取决于实际的硬件资源、负载和数据库工作负载等因素。通常需要进行实际测试和性能监控来确定最佳的配置值。

2.1. 如果字段上增加了索引也不一定

在正常情况下,如果 product_id 字段上存在合适的数据索引,PostgreSQL 应该会倾向于使用该索引来执行与 product_id 相关的查询。使用索引可以大大提高查询性能,因为它允许 PostgreSQL 快速定位到符合条件的数据行,而不必进行全表扫描。

然而,即使存在索引,有时候 PostgreSQL 也可能会选择不使用索引而是进行全表扫描。这种情况可能出现在以下情况下:

  1. 成本估算错误: 如果查询优化器错误地估计了索引扫描和全表扫描的成本,它可能会选择全表扫描而不是索引扫描。这种情况下,调整 effective_cache_size 参数可能会影响优化器的估算,使其更倾向于选择索引扫描。

  2. 索引不适用: 在某些情况下,即使存在索引,PostgreSQL 也可能选择不使用索引。例如,如果查询条件不是索引的前缀,或者查询条件使用了函数,这可能导致索引无法被使用。此外,如果统计信息不准确或者索引被损坏,也可能导致索引不被选择。

  3. 数据分布不均匀: 如果数据分布不均匀,即索引列上的值分布不均匀,有时候优化器可能会认为全表扫描更有效率,尤其是当需要检索大部分数据行时。

在这些情况下,虽然有索引但可能仍然会进行全表扫描。这种情况下可以考虑重新分析索引、收集统计信息、优化查询语句或者调整 PostgreSQL 的配置参数来影响查询规划器的行为。

总的来说,虽然索引可以大幅提高查询性能,但 PostgreSQL 的查询规划器决定执行计划的选择不仅取决于索引的存在,还受到多种因素的影响。合适地配置索引、收集统计信息、优化查询语句以及调整配置参数都是优化查询性能的重要步骤。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/200578.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lambda表达式用法汇总

Lambda表达式用法汇总 java8 中引入的 Lambda 表达式真的是个好东西&#xff0c;掌握之后&#xff0c;写代码更简洁了&#xff0c;码字效率也提升了不少&#xff0c;这里咱 们一起来看看 Lambada 表达式常见的写法&#xff0c;加深理解。 1、有参无返回值函数式接口 8 种写法…

【代码随想录】算法训练计划39

dp 1、62. 不同路径 题目&#xff1a; 求路径方案多少个 思路&#xff1a; 这道题就有点dp了哈 func uniquePaths(m int, n int) int {//dp&#xff0c;写过,代表的是多少种// 初始化dp : make([][]int, m)for i : range dp {dp[i] make([]int, n)dp[i][0] 1 // 代表到…

用友NC Cloud FileParserServlet反序列化RCE漏洞复现

0x01 产品简介 用友 NC Cloud 是一种商业级的企业资源规划云平台,为企业提供全面的管理解决方案,包括财务管理、采购管理、销售管理、人力资源管理等功能,实现企业的数字化转型和业务流程优化。 0x02 漏洞概述 用友 NC Cloud FileParserServlet接口存在反序列化代码执行漏…

response应用

文章目录 [TOC](文章目录) response说明一、response文件下载二、待补充。。。 response说明 response是指HttpServletResponse,该响应有很多的应用&#xff0c;比如像浏览器输出消息&#xff0c;下载文件&#xff0c;实现验证码等。 一、response文件下载 1.创建一个javaw…

springboot整合swagger

1&#xff09;简介&#xff1a; 作为后端开放人员&#xff0c;最烦的事就是自己写接口文档和别人没有写接口文档&#xff0c;不管是前端还是后端开发&#xff0c;多多少少都会被接口文档所折磨&#xff0c;前端会抱怨后端没有及时更新接口文档&#xff0c;而后端又会觉得编写接…

Spark-03: Spark SQL 基础编程

目录 1.Spark SQL 简介 2.SparkSession 3.Spark SQL 数据的读写 3.1 读写 TXT 文件 3.2 读写 CSV 文件 3.3 读写 JSON 文件 3.4 读写 Parquet 文件 3.5 读写 ORC 文件 3.6 读写MySQL数据库 4.Spark SQL 语法 4.1 SQL 语法 4.2 DSL 语法 1.Spark SQL 简介 Spark SQL…

备份和恢复Linux服务器上的HTTP配置

备份和恢复Linux服务器上的HTTP配置是一项重要的任务&#xff0c;它可以确保您的服务器在出现故障或配置错误时能够迅速恢复正常运行。下面我们将介绍如何备份和恢复Linux服务器上的HTTP配置。 备份HTTP配置 登录到Linux服务器上&#xff0c;并使用root权限。 备份HTTP配置文…

分部积分法

1.形式&#xff1a;u对v求积分uv-v对u求积分&#xff0c;一前一后&#xff0c;一般把三角函数&#xff0c;反三角函数&#xff0c;In,e的x次方提到d里面 2. 3. 4. 5. 6. 7. 当结果中出现要求的不要慌&#xff0c;不是1直接求&#xff0c;是1重新计算

一体化污水处理设备材质怎么选

在环保意识日益增强的今天&#xff0c;污水处理设备成为城市建设过程中的重要环节。而选择合适的一体化污水处理设备材质&#xff0c;则成为了一项重要的决策。本文将从专业的角度出发&#xff0c;为您解析一体化污水处理设备材质的选取。 首先&#xff0c;一体化污水处理设备材…

postman常用脚本

在参数中动态添加开始时间和结束时间的时间戳 1.先在collection中添加参数&#xff0c;这里的作用域是collection&#xff0c;也可以是其他的任何scope 2.在Pre-request Script 中设定开始时间和结束时间参数&#xff0c;比如昨天和今天的时间戳&#xff0c;下面是js代码 con…

Android Studio Hedgehog | 2023.1.1(刺猬)

Android Gradle 插件和 Android Studio 兼容性 Android Studio 构建系统基于 Gradle&#xff0c;并且 Android Gradle 插件 (AGP) 添加了一些特定于构建 Android 应用程序的功能。下表列出了每个版本的 Android Studio 所需的 AGP 版本。 Android Studio versionRequired AG…

Kubernetes 常用命令

集群信息&#xff1a; 1. 显示 Kubernetes 版本&#xff1a;kubectl version2. 显示集群信息&#xff1a;kubectl cluster-info3. 列出集群中的所有节点&#xff1a;kubectl get nodes4. 查看一个具体的节点详情&#xff1a;kubectl describe node <node-name>5. 列出所…

python学习:opencv+用鼠标画矩形和圆形

目录 步骤 定义数据 新建一个窗口黑色画布 显示黑色画布 添加鼠标回调函数 循环 一直显示图片 一直判断有没有按下字母 m 关闭所有窗口 鼠标回调函数 步骤 当鼠标按下记录坐标并记录鼠标标记位为true&#xff0c;移动的时候就会不断的画矩形或者圆&#xff0c;松下的时候就再…

vue项目通过宝塔部署之后,页面刷新后浏览器404页面

转载&#xff1a;vue项目通过宝塔部署之后&#xff0c;页面刷新后浏览器404页面。

ioc循环依赖怎么解决

在使用IoC&#xff08;Inversion of Control&#xff09;容器时&#xff0c;循环依赖是一个常见的问题。不同的IoC容器提供了不同的解决方案。在Spring框架中&#xff0c;常用的解决循环依赖的注解是 Lazy 和 Autowired。 1.Lazy 注解&#xff1a; 在Spring中&#xff0c;Lazy…

STM32F1中断NVIC

目录 1. 中断系统 2. 中断向量表 3. NVIC基本结构 4. NVIC优先级分组 5. NVIC程序编写 5.1 中断分组 5.2 中断结构体变量 5.3 中断通道选择 5.4 抢占优先级和响应优先级配置 6. 中断程序执行 1. 中断系统 中断&#xff1a;在主程序运行过程中&#xff0…

如何设计自动化测试脚本

企业中如何设计自动化测试脚本呢&#xff1f;今天我们就来为大家分享一些干货。 一、线性设计 线性脚本设计方式是以脚本的方式体现测试用例&#xff0c;是一种非结构化的编码方式&#xff0c;多数采用录制回放的方式&#xff0c;测试工程师通过录制回访的访问对被测系统进行…

基于JSDoc实现TypeScript类型安全的实践报告

在FEDay 2023中我讲了《从JS到TS无缝迁移的实践报告》【视频在这里在这里】&#xff0c;是将一个传统的JS项目&#xff08;mochajs/mocha&#xff09;迁移到TypeScript环境的全程。其中提到了一件事情&#xff0c;就是“可以通过JSDoc/TSDoc来生成.d.ts”&#xff0c;从而实现T…

FastAPI的路由

前言 回想一下我们在hello world程序里面做了哪些事情&#xff1f; 还是先把那段著名的程序的代码贴出来欣赏一下吧。 from fastapi import FastAPIapp FastAPI()app.get("/") async def root():return {"message": "Hello World"}app.get(&q…

mvc模式test2

关于上篇book.java中使用类型不一样导致的报错 是在bookdao.java中解决 bookservlet.java package servlet; import java.io.IOException; import beans.Book; import dao.BookDao; import java.util.ArrayList; import javax.servlet.ServletException; import javax.servl…