• pg的sql统计信息,慢查询等


    背景

    数据库运维过程中,dba都比较关注sql的执行时间。研发在数据库应用开发上,速度慢的sql比比皆是,很多速度很慢都是sql写得不好,效率不高,执行过程中也会造成数据库的负载过大。比如无用的去重,无效的条件,不必要的子查询,sql用不上的索引。而对于这些不符合要求的sql,首先要去把这些sql找出来。

    措施

    pg数据库提供了统计信息的功能来查找,下面介绍两种办法:

    • 修改日志参数,记录超过指定时间的sql,以及当时的执行时间
    • 通过pg_stat_statements统计

    修改日志参数

    log_min_duration_statement:从log中找出执行超过一定时间的sql。这个参数是设置执行最小多长时间的sql输出到log,例如输出执行超过3秒的sql,可以设置log_min_duration_statement = 3s。这个参数设置为-1是无效,默认为-1。设置为0是输出所有的sql,但这样会增加服务器的负担,一般不要设置太低的值。

    auto_explain功能:在Postgresql8.4版本后新增了该功能。默认这个功能是不可用的,需要配置如下。这样系统在执行的时候遇到超过2秒的SQL的话,,会自动把sql输出到log,这样看log就更容易找到问题点了。

    shared_preload_libraries = 'auto_explain'
    custom_variable_classes = 'auto_explain'   #PostgreSQL9.2版本后此参数已取消,不需要设置
    auto_explain.log_min_duration = 2s
    

    实际log查看:

    < 2019-11-12 15:40:30.284 CST > 日志:  执行时间: 3048.397 ms 语句: SELECT * FROM indexedresult WHERE searchtitle LIKE '%好%' ORDER BY  searchtitle
    

    加载pg_stat_statements模块

    pg_stat_statements模块提供了一种方法,用于跟踪所有由服务器执行的sql语句的统计,例如,语句总调用次数,总执行时间,从内存中读取的块数,从磁盘读取的块数等信息。在添加或删除模块pg_stat_statements模块时,需要额外的共享内存,所以必须重启数据库。pg_stat_statements模块加载会消耗部分的内存,可以通过pg_stat_statements.max * track_activity_query_size来计算。这个值是比较小的,假如pg_stat_statements.max 值为 10000, track_activity_query_size值为4096,也就消耗了40M内存。

    参考配置如下:

    shared_preload_libraries = 'pg_stat_statements '
    track_activity_query_size = 4096                #SQL文本的最大大小,4K
    custom_variable_classes = 'pg_stat_statements '  #PostgreSQL9.2版本后此参数已取消,不需要设置
    pg_stat_statements.max = 10000                #跟踪模块中的语句的最大数目
    pg_stat_statements.track = all
    

    参数配置好后,需要重启数据库。注意该模块是区分数据库的,不是全局共享的。如果无法查询,可能需要在对应的数据库下面加载pg_stat_statements模块。运行如下语句:

    CREATE EXTENSION pg_stat_statements;
    

    配置好pg_stat_statements模块后,经过一段时间的运行,我们就可以通过pg_stat_statements视图来统计效率低的SQL,语句如下:

    --查询语句总调用次数大于10次,平均运行时间倒序的SQL
    SELECT t.userid,
            t.dbid,
            t.query || ';',
            t.calls,
            t.total_time,
            t.rows,
            t.total_time / t.calls
      FROM pg_stat_statements t
     WHERE (t.calls IS NOT NULL OR t.calls <> 0)
       AND t.query !~ '^COPY|<insufficient privilege'
       AND t.calls > 10
     ORDER BY 7 DESC;
    
    

    总结

    上面两种方法可以根据实际业务需要来进行,比如仅仅需要查看问题sql的情况可以用第一种,如果需要深入分析sql的类别,执行次数,执行时间等更丰富的信息可以采用第二种方式,根据调用的次数来设计缓存也是非常重要的依据。

  • 相关阅读:
    Spring IoC容器
    Spring Bean定义
    Spring框架 体系结构,一个简单的Spring程序
    Spring基础知识汇总 Java开发必看
    mybatis 优缺点(优点和缺点)
    MyBatis:<selectKey> #keyProperty、keyColumn、order
    fatal: The upstream branch of your current branch does not match the name of your current branch
    808端口被 OneApp.IGCC.WinService.exe占用的问题
    浅析如何使docker容器可以进行ssh连接
    浅析如何为正在运行的容器添加端口映射
  • 原文地址:https://www.cnblogs.com/easonbook/p/11843716.html
Copyright © 2020-2023  润新知