一直都在从事数据库性能测试方面的工作,遇到过各种各样的性能问题。深感若没有SQL执行信息,数据库性能分析便无从谈起。
利用业余时间修改了Postgres8.3.3的源代码,在其中加入了统计SQL执行信息的功能。它可以显示每条 SQL 语句的执行次数、执行时间、消耗的CPU时间、读cache次数、命中cache 次数。
它可以帮你找到执行时间最长,消耗资源最多的SQL。对于事务处理,如果一条SQL语句在执行时读cache的次数达到了2000以上,极有可能是优化器产生的执行计划太差,
如果你在使用potgres时遇到性能问题,不妨使用一下。
压缩后的软件包大约有5M,需要的朋友可以给我发邮件postgres_fan@yahoo.com.cn,我会发给你,是一个完整的postgres软件包, 直接解开便可使用。 现在只有Linux 32位版的, 没有做windows版的,精力实在有限。
基于的postgres的版本是8.3.3, 使用旧版本的需要升级。
只需要用psql连上数据库,输入命令"dump sql_stats;" 或 "dump sql_stats reset;", 所有SQL语句的执行信息便会被写到一个数据文件中,该数据文件位于子目录sql_dump下面。
假定你的数据库位于目录/home/postgres/database 下,那么你可以在/home/postgres/database/sql_dump下找到该数据文件。 该数据文件的名字以sql_dump打头,后面是文件建立的时间,
如sql_dump_2008_09_24_12_42_25 表示该文件是2008年9月24日12点42分45秒创建的。如果是第一次执行dump sql_stats,它将会将所有的从数据库启动到执行该命令期间运行的
SQL语句的信息导出到外部文件中,否则,它将会将所有的从上次执行dump sql_stats reset命令到本次执行该命令期间运行的SQL语句的信息导出到外部文件中。如果在Linux
下查看该文件,LANG环境变量应设为zh_CN.gb1803(我用的是openSuse 11)。
下面是我的机器上的一个数据文件实例, 其中含有两条SQL语句的执行信息:
yan@yan:/home/postgres_bin/database/sql_dump> more sql_dump_2008_09_24_12_42_25
-------------------------------------------------------------------------------------------------
第1条SQL
drop table pxtest1 ;
执行次数:1
读cache次数:103 命中cache次数:103 执行时间: 1661.000000 消耗的CPU时间:0.000000
平均读cache次数:103 平均命中cache次数:103 平均执行时间: 1661.000000 平均消耗的CPU时间:0.000000
-------------------------------------------------------------------------------------------------
第2条SQL
select * from foo where id in ( select id2 from ( select id1 , id2 from bar union select id1 , id2 from bar ) as s ) ;
执行次数:1
读cache次数:0 命中cache次数:0 执行时间: 342.000000 消耗的CPU时间:0.000000
平均读cache次数:0 平均命中cache次数:0 平均执行时间: 342.000000 平均消耗的CPU时间:0.000000
-------------------------------------------------------------------------------------------------
以第一条SQL为例,第一行显示的是具体的SQL语句,第二行显示的是该语句的执行次数, 第三行显示的是这条语句执行时总的读cache次数、总的命中cache次数、总的执行时间和总的CPU时间。
第四行显示的是平均每次执行的读cache次数、命中cache次数、执行时间和消耗的CPU时间,实际上就是用第三行的值除以SQL语句的执行次数得来的。注意执行时间和CPU时间的单位是0.000001秒,即微秒。
dump sql_stats 与 dump sql_stats reset的区别在于,加上reset以后,所有SQL执行统计信息在被导出到外部文件中后,数据库将会清除掉这些信息,重新开始统计。没有加reset,则所有
SQL执行统计信息在被导出到外部文件中后,还会继续保存在数据库中。
另外,该工具在统计SQL执行信息时,会对SQL语句进行一定的变换, 如果SQL语句中含有数据或字符型等常量,这些常量将会被变换成$1,$2, ..., $n。
例如: select * from test where size > 100 将会被变换成 select * from test where size > $1, 同样 select * from test where size > 200
也会被变换成 select * from test where size > $1。所以这两条语句的的执行信息会被合并到一起, 作为一条语句来处理。再举一个例子,
select * from test where size > 100 and size < 200 会被变换成 select * from test where size > $1 and size < $2, 所以它与上面两条语句是
不同的,将会作为一条新的语句来收集统计信息。