首页 > 数据库 >数据库占用大量内存的检测和优化(PostgreSQL)

数据库占用大量内存的检测和优化(PostgreSQL)

时间:2023-04-26 11:56:01浏览次数:30  
标签:PostgreSQL 数据库 元组 索引 内存 查询 优化 性能

select * from pg_stat_user_tables where n_live_tup > 100000 and seq_scan > 0 order by seq_tup_read desc limit 10;

这个 SQL 查询用于检查在 PostgreSQL 数据库中,哪些用户表(user tables)的行数(live tuples)超过 100,000,且进行了顺序扫描(sequential scans)。查询结果会按顺序读取的元组数(sequential tuple reads)降序排列,并显示前 10 个表。

查询解释如下:

  • pg_stat_user_tables:PostgreSQL 系统表,提供关于用户表的统计信息。
  • n_live_tup:表中当前活动元组(行)的数量。
  • seq_scan:对表进行的顺序扫描次数。
  • seq_tup_read:顺序扫描期间读取的元组数量。

执行这个查询可以帮助您分析数据库性能,找出可能需要优化的表。例如,如果某个表有大量的顺序扫描,您可能需要考虑为该表添加索引以提高查询性能。

 

  • relid: 表的 OID (对象标识符)。
  • schemaname: 包含该表的模式的名称。
  • relname: 表名。
  • seq_scan: 对表进行的顺序扫描次数。
  • seq_tup_read: 顺序扫描期间读取的元组数量。
  • idx_scan: 对表进行的索引扫描次数。
  • idx_tup_fetch: 索引扫描期间读取的元组数量。
  • n_ins: 插入该表的元组数量。
  • n_upd: 更新该表的元组数量。
  • n_del: 删除该表的元组数量。
  • n_hot_upd: 表中的 "热" 更新的元组数量。热更新是指在同一数据块中进行的更新操作。
  • n_live_tup: 表中当前活动元组(行)的数量。
  • n_dead_tup: 表中当前已删除的元组数量。
  • n_mod_since_analyze: 自上次分析操作(ANALYZE 命令)后修改的元组数量。
  • last_vacuum: 最后一次对表执行 VACUUM 操作的时间戳。
  • last_autovacuum: 最后一次自动执行 VACUUM 操作的时间戳。
  • last_analyze: 最后一次对表执行 ANALYZE 操作的时间戳。
  • last_autoanalyze: 最后一次自动执行 ANALYZE 操作的时间戳。
  • vacuum_count: 表上执行的 VACUUM 操作次数。
  • autovacuum_count: 表上自动执行的 VACUUM 操作次数。
  • analyze_count: 表上执行的 ANALYZE 操作次数。
  • autoanalyze_count: 表上自动执行的 ANALYZE 操作次数。

这些字段可以帮助您分析数据库表的使用情况,以便进行性能优化。例如,通过查看 seq_scanidx_scan,您可以了解表上的顺序扫描和索引扫描的次数,从而判断是否需要添加或优化索引。同时,查看 last_vacuumlast_analyze 也有助于了解表的维护情况。

 

根据您提供的查询,您似乎关心那些具有大量活动元组和顺序扫描的表。在 PostgreSQL 数据库中优化这些表的性能,可以从以下几个方面进行:

  1. 添加或优化索引: 对于具有大量顺序扫描的表,请检查您是否可以添加更多索引以减少顺序扫描。检查查询,看看是否有任何频繁用于过滤条件的列,这些列可能会受益于索引。同时,确保现有索引已经正确地维护和使用。

  2. 调整 PostgreSQL 配置参数: 您可以通过调整 PostgreSQL 的配置参数来优化数据库性能。例如,增加 shared_bufferseffective_cache_sizework_mem 可以改善数据库性能。请注意,调整这些参数可能需要根据系统资源和实际工作负载进行权衡。

  3. 表分区: 如果表非常大,您可以考虑使用表分区。分区允许您将大型表分解为较小、更易管理的部分。这样可以加快查询速度,因为查询只需要访问感兴趣的分区,而不是整个表。

  4. 定期维护: 使用 VACUUMANALYZE 命令定期清理表并更新统计信息。这将帮助优化器更好地了解数据分布,从而生成更有效的查询计划。您可以设置自动维护任务(autovacuum)来自动执行这些操作。

  5. 优化查询: 分析执行缓慢的查询,看看是否可以通过更改查询结构或使用更高效的操作来提高性能。您可以使用 EXPLAINEXPLAIN ANALYZE 命令来了解查询的执行计划以及如何优化。

  6. 硬件和数据库位置: 如果您的系统硬件资源有限,例如 CPU、内存或磁盘速度,那么考虑升级硬件或将数据库移到更高性能的服务器上。

  7. 并行处理和负载平衡: 如果可能的话,使用并行查询和负载平衡来分摊工作负载。这可以在多个 CPU 核心或服务器之间分配查询处理任务,从而加快查询速度。

对于运行 Odoo 服务的系统,特别要关注以下几点:

  • 检查 Odoo 的配置文件,确保数据库连接参数、工作线程数等已经正确设置。
  • 使用 Odoo 的监控工具来检查系统性能,找出可能的瓶颈。
  • 在开发自定义模块或扩展现有模块时,请确保遵循最佳实践,以免影响性能。

请注意,优化数据库性能通常需要

 多次迭代和持续关注。要实现最佳性能,您需要不断监控数据库和应用程序性能,随着工作负载和数据量的变化,不断调整和优化配置。

继续优化的其他建议:

  1. 使用连接池: 使用连接池可以减少建立和关闭数据库连接的开销。在运行 Odoo 服务时,可以考虑使用像 PgBouncer 这样的连接池。

  2. 存储过程和函数: 如果有一些复杂的查询或业务逻辑,可以考虑使用存储过程或函数。这将有助于减少网络传输的数据量,提高应用程序性能。

  3. 优化数据模型: 检查数据模型,确保表之间的关系已经正确建立,避免冗余数据和不一致。优化数据模型可以提高查询性能。

  4. 监控和日志记录: 设置监控和日志记录工具,以定期检查数据库性能。这将帮助您识别性能问题,从而更好地优化数据库。

  5. 物化视图: 如果有一些经常使用的聚合查询,可以考虑使用物化视图。物化视图将查询结果存储为一个表,而不是实时计算。这样可以加快查询速度,但需要注意数据更新和维护。

  6. 使用只读副本: 如果有大量的只读查询,可以考虑设置一个只读副本。这将使读取负载分散到多个服务器,从而提高性能。

在进行任何优化更改之前,请确保对现有系统进行备份,以便在出现问题时能够恢复。同时,确保在生产环境中应用更改之前,先在测试环境中验证更改的效果。这将确保您的系统在优化过程中保持稳定和可靠。

 使用分区表: 如果您的表非常大且难以管理,可以考虑使用分区表。分区表将大表分解为多个小表,这有助于提高查询性能和管理效率。
  1. *避免使用 SELECT 当编写查询时,避免使用 SELECT * 从表中检索所有列。尽量只选择所需的列,以减少数据传输量和查询时间。

  2. 使用索引覆盖查询: 索引覆盖查询是一种查询,其所有列都来自索引,而不需要访问表本身。尝试优化查询,以便只从索引中检索数据,从而提高查询性能。

  3. 批量插入和更新: 当需要插入或更新大量数据时,尽量使用批量插入和更新。批量操作比单个操作更有效率,因为它们减少了数据库管理系统的开销。

  4. 适当的事务管理: 确保在应用程序中正确使用事务。长时间运行的事务可能会锁定资源并降低性能。尝试将事务保持在最小时间范围内,并在可能的情况下使用只读事务。

  5. 定期清理和维护: 定期对数据库进行清理和维护,例如删除不再需要的数据,压缩和整理表。这将有助于提高性能并减少磁盘空间使用。

  6. 监控并调整内存和资源使用: 观察数据库服务器的内存和资源使用情况,根据需要调整配置参数。例如,您可能需要增加工作内存或共享缓冲区大小以提高查询性能。

在执行任何优化操作之前,始终确保对现有系统进行备份,以便在出现问题时能够恢复。同时,在应用生产环境中的更改之前,先在测试环境中验证更改的效果。这将确保您的系统在优化过程中保持稳定和可靠。请注意,每个数据库和应用程序都有其独特的性能特征,因此一些建议可能不适用于您的特定情况。在实施任何更改时,请务必进行充分的测试和评估。

   

标签:PostgreSQL,数据库,元组,索引,内存,查询,优化,性能
From: https://www.cnblogs.com/lyt263/p/17355211.html

相关文章

  • 从数据库查询权限信息与自定义失败处理
    从数据库查询权限信息代码实现我们只需要根据用户id去查询到其所对应的权限信息即可。​  所以我们可以先定义个mapper,其中提供一个方法可以根据userid查询权限信息。packagecom.example.qinghuatokendemo.Mapper;importc......
  • node同步查询数据库(mysql)
    mysql模块默认异步操作,在写一些简单脚本时会比较痛苦,可以通过async/await和Promise封装成同步操作asyncfunctionquery(connection,sql){returnnewPromise((resolve,reject)=>{connection.query(sql,function(error,results){if(error)reject(resu......
  • sql数据库连接
    前言作为数据存储的数据库,近年来发展飞快,在早期的程序自我存储到后面的独立出中间件服务,再到集群,不可谓不快了。早期的sql数据库一枝独秀,到后面的Nosql,还有azure安全,五花八门,教人学不过来阿。一mysql数据库的golang操作针对数据库操作,往往需要安装实体数据库和对应的数据库驱......
  • JDBC访问数据库
    下载,安装MySQL(下载地址:https://www.mysql.com/downloads/)创建数据库——createdatabase<数据库名>创建用户——mysql>grantallprivilegeson数据库名.*to新用户名@locahost identifiedby‘密码’;使用DDL创建表——createtable表名(字段名数据类型是否主键/非空)使用DML操......
  • 数据库实践课
    一、实验目的:掌握使用SQL语言进行数据定义和数据操纵的方法。二、实验要求:建立一个数据库stumanage,建立三个关系表student,course,sc。向表中插入数据,然后对数据进行删除、修改等操作,对关系、数据库进行删除操作。三、实验步骤:1、开始→程序→MicrosoftSQLServer→SQL......
  • 08 内存(下)实现内存页的分配和释放
    初始化完内存页和内存区,接下来就实现分配和释放内存页面;内存页的分配: 内存分配页面接口函数:mm_division_pages,进而调用mm_divpages_fmwk内存分配页面框架函数,此函数先返回对应的内存区结构的指针,然后调用内存分配核心函数mm_divpages_core,返回msadsc_t结构体指针,包含返回......
  • redis删除数据后内存释放问题
    这不是Redis本身的问题,Redis本身确实已经调用free释放这些内存。这应该是使用的底层C运行时的问题。就glibc来说,在分配大于128k的内存时使用mmap,而使用brk/sbrk在heap中分配小内存。通过mmap申请的内存在调用free后能马上返还给系统,而heap中的内存就不一定,除非释放的内存是heap中......
  • MySQL数据库
     DB哥MySQL高级教程-系统学习MySQL共149课时加我微信公众号免费学:DB哥文末有MySQL高级课程目录一、MySQL数据库数据库,又称为数据管理系统,可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的资料运行新增、查询、更新、删除等操作。关系型数据库,存储的格式可以直......
  • PostgreSQL插件那么多,怎样管理最高效?
    摘要:华为云RDSforPostgreSQL通过插件管理功能,很好地解决了PostgreSQL版本与插件耦合的问题,帮助用户更直观、更快速地安装管理数据库插件。本文分享自华为云社区《PostgreSQL插件那么多,怎样管理最高效?》,作者:GaussDB数据库。云服务环境下,如何让客户更方便地在各个PostgreSQL的......
  • lightdb/postgresql中的统计信息详解
    和oracle,lightdb也支持单列和多列统计信息,见14.2. StatisticsUsedbythePlanner(light-pg.com)。默认情况下,analyze收集的统计信息是针对单列的,多个列之间通常没有依赖关系,在多个where里面,这容易导致基数计算失真。planner使用statistics的方式,在sql执行的plan步骤,Chapter......