{"id":32353,"date":"2019-10-31T21:46:32","date_gmt":"2019-10-31T18:46:32","guid":{"rendered":"https:\/\/prohoster.info\/blog\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting\/"},"modified":"2019-10-31T21:46:32","modified_gmt":"2019-10-31T18:46:32","slug":"monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting","title":{"rendered":"Monitoramento de desempenho de consultas PostgreSQL. Parte 1 - Reportagem","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Engenheiro \u2014 em latim \u2014 inspirado.<br \/>\nO engenheiro pode tudo. (c) R.Diesel.<br \/>\n<i>Ep\u00edgrafes.<\/i><br \/>\n<img decoding=\"async\" alt=\"Monitoramento de desempenho de consultas PostgreSQL. Parte 1 - Reportagem\" src=\"\/wp-content\/uploads\/2019\/04\/9a2640267ea05006b94e03642b864ddc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Ou a hist\u00f3ria sobre por que o administrador de banco de dados deve lembrar de seu passado como programador. <\/i><\/p>\n<h2>Pref\u00e1cio<\/h2>\n<p>\nTodos os nomes foram alterados. Qualquer semelhan\u00e7a \u00e9 mera coincid\u00eancia. O material representa exclusivamente a opini\u00e3o pessoal do autor.<\/p>\n<blockquote><p><b>Isen\u00e7\u00e3o de garantias:<\/b> <i>no planejado ciclo de artigos n\u00e3o haver\u00e1 descri\u00e7\u00e3o detalhada e precisa das tabelas e scripts utilizados. Os materiais n\u00e3o podem ser usados imediatamente \"AS IS\". <br \/>\nPrimeiro, devido ao grande volume do material, <br \/>\nem segundo lugar, devido \u00e0 adequa\u00e7\u00e3o com a base de produ\u00e7\u00e3o do cliente real. <br \/>\nPortanto, nos artigos ser\u00e3o apresentados apenas ideias e descri\u00e7\u00f5es de forma geral. <br \/>\nTalvez no futuro o sistema evolua para o n\u00edvel de publica\u00e7\u00e3o no GitHub, ou talvez n\u00e3o. O tempo dir\u00e1.<\/i><\/p><\/blockquote>\n<p>\nO in\u00edcio da hist\u00f3ria \u2014 \"<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/icl_services\/blog\/446314\/\">Voc\u00ea se lembra de como tudo come\u00e7ou<\/a><\/noindex>\u00bb.<br \/>\nO que resultou, de maneira geral \u2014 \"<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/444988\/\">S\u00edntese como um dos m\u00e9todos para melhorar o desempenho do PostgreSQL<\/a><\/noindex>\u00bb<\/p>\n<h2>Por que tudo isso para mim?<\/h2>\n<p>\nBem, primeiro, para n\u00e3o esquecer, relembrando na aposentadoria os gloriosos dias. <br \/>\nEm segundo lugar, para sistematizar o que foi escrito. Porque j\u00e1, \u00e0s vezes, come\u00e7o a me confundir e esquecer partes espec\u00edficas. <\/p>\n<p>E o mais importante \u2014 talvez isso possa ser \u00fatil para algu\u00e9m e ajudar a n\u00e3o reinventar a roda e n\u00e3o pisar em um garfo. Em outras palavras, melhorar seu karma (n\u00e3o o de Habr). Porque a coisa mais valiosa neste mundo s\u00e3o as ideias. O principal \u00e9 encontrar a ideia. E realizar a ideia na realidade j\u00e1 \u00e9 uma quest\u00e3o puramente t\u00e9cnica.<\/p>\n<p>Ent\u00e3o, vamos come\u00e7ar, devagar...<\/p>\n<h2>Defini\u00e7\u00e3o do problema.<\/h2>\n<p><\/p>\n<h3>Temos: <\/h3>\n<p>\nBanco de dados PostgreSQL (10.5), de carga mista (OLTP+DSS), de m\u00e9dia-baixa carga, situado na nuvem AWS. <br \/>\nA monitoriza\u00e7\u00e3o do banco de dados est\u00e1 ausente, a monitoriza\u00e7\u00e3o da infraestrutura \u00e9 feita por meio dos recursos padr\u00e3o da AWS na configura\u00e7\u00e3o m\u00ednima.<\/p>\n<h3>\u00c9 necess\u00e1rio:<\/h3>\n<p>\nMonitorar o desempenho e o estado do banco de dados, encontrar e ter informa\u00e7\u00f5es iniciais para otimizar consultas pesadas ao BD.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Uma breve introdu\u00e7\u00e3o ou an\u00e1lise das op\u00e7\u00f5es de solu\u00e7\u00e3o<\/h2>\n<p>\nPara come\u00e7ar, vamos tentar analisar as op\u00e7\u00f5es de solu\u00e7\u00e3o do problema do ponto de vista de uma an\u00e1lise comparativa de benef\u00edcios e inconvenientes para o engenheiro, enquanto os benef\u00edcios e preju\u00edzos da gest\u00e3o ficam a cargo de quem \u00e9 respons\u00e1vel de acordo com os quadros.<\/p>\n<h3>Op\u00e7\u00e3o 1 \u2014 \"Trabalhando sob demanda\"<\/h3>\n<p>\nDeixamos tudo como est\u00e1. Se o cliente n\u00e3o estiver satisfeito com algo na funcionalidade, desempenho do banco de dados ou do aplicativo, ele informar\u00e1 os engenheiros de DBA por e-mail ou criando um incidente no sistema de tickets. <br \/>\nO engenheiro, ao receber a notifica\u00e7\u00e3o, vai analisar o problema, sugerir uma solu\u00e7\u00e3o ou adiar a quest\u00e3o, esperando que tudo se resolva por si s\u00f3, e de qualquer forma, tudo logo ser\u00e1 esquecido.<br \/>\n<b class=\"spoiler_title\">Biscoitos e p\u00e3ezinhos, hematomas e incha\u00e7os<\/b><b>Biscoitos e p\u00e3ezinhos:<\/b><br \/>\n1. N\u00e3o \u00e9 necess\u00e1rio fazer nada em excesso<br \/>\n2. Sempre h\u00e1 uma oportunidade de se esquivar e relaxar. <br \/>\n3. Um monte de tempo que pode ser gastado \u00e0 vontade.<br \/>\n<b>Hematomas e incha\u00e7os:<\/b><br \/>\n1. Mais cedo ou mais tarde, o cliente refletir\u00e1 sobre a ess\u00eancia da exist\u00eancia e a justi\u00e7a universal neste mundo e mais uma vez se perguntar\u00e1 - por que estou pagando por isso? A consequ\u00eancia \u00e9 sempre a mesma \u2014 a \u00fanica quest\u00e3o \u00e9 quando o cliente ficar\u00e1 entediado e se despedir\u00e1. E a alimenta\u00e7\u00e3o se esvaziar\u00e1. Isso \u00e9 triste.<br \/>\n2. Desenvolvimento do engenheiro \u2014 zero.<br \/>\n3. Dificuldades no planejamento do trabalho e carga de servi\u00e7o <\/p>\n<h3>Op\u00e7\u00e3o 2 - 'Dan\u00e7amos com tambores, vendemos e cal\u00e7amos'<\/h3>\n<p>\n<b>Ponto 1<\/b>-Por que precisamos de um sistema de monitoramento? Vamos receber tudo atrav\u00e9s de solicita\u00e7\u00f5es. Executamos um monte de solicita\u00e7\u00f5es para o dicion\u00e1rio de dados e visualiza\u00e7\u00f5es din\u00e2micas, ativamos v\u00e1rios contadores, reunimos tudo em tabelas, periodicamente analisamos listas e tabelas. No resultado, temos gr\u00e1ficos bonitos ou nem t\u00e3o bonitos, tabelas, relat\u00f3rios. O principal \u00e9 ter mais, mais.<br \/>\n<b>Ponto 2<\/b>-Geramos atividade \u2014 iniciamos a an\u00e1lise de tudo isso.<br \/>\n<b>Ponto 3<\/b>-Preparar um documento, que chamamos simplesmente de \u2014 'como organizar nosso banco de dados'.<br \/>\n<b>Ponto 4<\/b>-O cliente, ao ver toda essa maravilha de gr\u00e1ficos e n\u00fameros, fica numa ingenuidade infantil acreditando \u2014 agora sim, tudo vai funcionar em breve. E, de forma f\u00e1cil e indolor, se despede de seus recursos financeiros. A gest\u00e3o tamb\u00e9m est\u00e1 confiante \u2014 os engenheiros est\u00e3o trabalhando duro. Carga no m\u00e1ximo. <br \/>\n<b>Ponto 5<\/b>-Repetir regularmente o Ponto 1.<br \/>\n<b class=\"spoiler_title\">Biscoitos e p\u00e3ezinhos, hematomas e incha\u00e7os<\/b><b>Biscoitos e p\u00e3ezinhos: <\/b><br \/>\n1. A vida dos gerentes e engenheiros \u00e9 simples, previs\u00edvel e cheia de atividades. Tudo zumbindo, todos ocupados. <br \/>\n2. A vida do cliente tamb\u00e9m n\u00e3o \u00e9 ruim \u2014 ele sempre acredita que precisa apenas esperar um pouco e tudo se resolver\u00e1. N\u00e3o se resolve, bem, o que fazer \u2014 o mundo \u00e9 injusto, na pr\u00f3xima vida \u2014 ter\u00e1 sorte.<br \/>\n<b>Hematomas e incha\u00e7os:<\/b><br \/>\n1. Tarde ou cedo, surgir\u00e1 um fornecedor mais \u00e1gil oferecendo o mesmo servi\u00e7o, mas um pouco mais barato. E se o resultado for o mesmo, por que pagar mais? Isso, novamente, levar\u00e1 ao desaparecimento da fonte de renda.<br \/>\n2. Isto \u00e9 entediante. Assim como qualquer atividade sem sentido.<br \/>\n3. Assim como na op\u00e7\u00e3o anterior, n\u00e3o h\u00e1 desenvolvimento algum. Mas para o engenheiro, a desvantagem \u00e9 que, ao contr\u00e1rio da primeira op\u00e7\u00e3o, aqui \u00e9 necess\u00e1rio gerar constantemente a Base de Dados de Invent\u00e1rio. E isso consome tempo, que poderia ser usado para o pr\u00f3prio benef\u00edcio. Afinal, se voc\u00ea n\u00e3o cuidar de si mesmo, ningu\u00e9m se importar\u00e1 com voc\u00ea.<\/p>\n<h3>Op\u00e7\u00e3o 3 - N\u00e3o \u00e9 preciso reinventar a roda, \u00e9 preciso compr\u00e1-la e utilizar.<\/h3>\n<p>\nEngenheiros de outras empresas n\u00e3o comem pizza com cerveja \u00e0 toa (ah, os gloriosos tempos de S\u00e3o Petersburgo nos anos 90). Vamos usar sistemas de monitoramento que j\u00e1 foram desenvolvidos, ajustados e que funcionam, e que, na verdade, trazem benef\u00edcios (pelo menos para seus criadores).<br \/>\n<b class=\"spoiler_title\">Biscoitos e p\u00e3ezinhos, hematomas e incha\u00e7os<\/b><b>Biscoitos e p\u00e3ezinhos:<\/b><br \/>\n1. N\u00e3o \u00e9 preciso perder tempo inventando o que j\u00e1 foi inventado. Pegue e use.<br \/>\n2. Sistemas de monitoramento n\u00e3o s\u00e3o feitos por tolos e, com certeza, s\u00e3o \u00fateis.<br \/>\n3. Sistemas de monitoramento que est\u00e3o em funcionamento geralmente oferecem informa\u00e7\u00f5es \u00fateis e filtradas. <br \/>\n<b>Hematomas e incha\u00e7os:<\/b><br \/>\n1. O engenheiro, nesse caso, n\u00e3o \u00e9 um engenheiro, mas apenas um usu\u00e1rio de um produto alheio. Ou um usu\u00e1rio.<br \/>\n2. \u00c9 preciso convencer o cliente da necessidade de comprar algo que, na verdade, ele n\u00e3o quer entender, nem deve, e o or\u00e7amento do ano j\u00e1 est\u00e1 aprovado e n\u00e3o vai mudar. Depois, \u00e9 necess\u00e1rio alocar um recurso separado e ajustar para um sistema espec\u00edfico. Ou seja, primeiro ter\u00e1 que pagar, pagar e pagar de novo. E o cliente \u00e9 avarento. Essa \u00e9 a norma da vida.<\/p>\n<h2>O que fazer - Turgenev? Sua pergunta \u00e9 bastante pertinente. (c)<\/h2>\n<p>\nNessa situa\u00e7\u00e3o espec\u00edfica, \u00e9 poss\u00edvel agir de uma forma ligeiramente diferente - <b>vamos fazer nosso pr\u00f3prio sistema de monitoramento. <\/b><br \/>\n<img decoding=\"async\" alt=\"Monitoramento de desempenho de consultas PostgreSQL. Parte 1 - Reportagem\" src=\"\/wp-content\/uploads\/2019\/04\/b59a3ad9e16b68c0fbc962a61d571c52.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nEmbora n\u00e3o um sistema exatamente, no sentido completo da palavra, isso seria um tanto exagerado e presun\u00e7oso, mas ao menos ser\u00e1 uma forma de facilitar nossa tarefa e coletar mais informa\u00e7\u00f5es para resolver incidentes de desempenho. Para n\u00e3o nos encontrarmos na situa\u00e7\u00e3o - \"v\u00e1 para onde voc\u00ea n\u00e3o sabe, encontre o que n\u00e3o sabe\".<\/p>\n<h4>Quais s\u00e3o os pr\u00f3s e contras dessa op\u00e7\u00e3o:<\/h4>\n<p><b>Acesso direto aos sistemas de cabos transpac\u00edficos. Ping m\u00ednimo para a China, Jap\u00e3o, Austr\u00e1lia e costa oeste dos EUA.<\/b><br \/>\n1. Isso \u00e9 interessante. Pelo menos \u00e9 mais interessante do que as constantes \"shrink datafile, alter tablespace, etc.\" <br \/>\n2. Estas s\u00e3o novas habilidades e um novo desenvolvimento. O que, a longo prazo, dar\u00e1 as recompensas merecidas.<br \/>\n<b>Pontos negativos:<\/b><br \/>\n1. Ser\u00e1 necess\u00e1rio trabalhar. Trabalhar muito. <br \/>\n2. Ser\u00e1 necess\u00e1rio explicar regularmente o sentido e as perspectivas de toda a atividade.<br \/>\n3. Ser\u00e1 preciso abrir m\u00e3o de algo, j\u00e1 que o \u00fanico recurso dispon\u00edvel para o engenheiro \u2014 o tempo \u2014 \u00e9 limitado pelo Universo. <br \/>\n<b>4. O mais assustador e desagrad\u00e1vel<\/b> \u2014 \u00e9 que no final pode resultar em algo como 'Nem um ratinho, nem um sapo, mas uma criatura desconhecida'.<\/p>\n<p><b>Quem n\u00e3o arrisca, n\u00e3o toma champanhe.<\/b><br \/>\nAssim \u2014 come\u00e7a a parte mais interessante.<\/p>\n<h2>A ideia geral \u2014 esquematicamente<\/h2>\n<p>\n<img decoding=\"async\" alt=\"Monitoramento de desempenho de consultas PostgreSQL. Parte 1 - Reportagem\" src=\"\/wp-content\/uploads\/2019\/04\/d1ae2ddc1d4c43353fe93eebdaa8b81a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n(<i>A ilustra\u00e7\u00e3o foi retirada de um artigo<\/i> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/444988\/\">S\u00edntese como um dos m\u00e9todos para melhorar o desempenho do PostgreSQL<\/a><\/noindex>\u00bb)<\/p>\n<p>Explica\u00e7\u00e3o:<\/p>\n<ul>\n<li> Na base de dados alvo, \u00e9 instalado a extens\u00e3o padr\u00e3o do PostgreSQL \u2014 \u201cpg_stat_statements\u201d. <\/li>\n<li>Na base de dados de monitoramento, criamos um conjunto de tabelas de servi\u00e7o para armazenar a hist\u00f3ria do pg_stat_statements na etapa inicial e para configurar m\u00e9tricas e monitoramento posteriormente.<\/li>\n<li> No host de monitoramento, criamos um conjunto de scripts bash, incluindo para gera\u00e7\u00e3o de incidentes no sistema de tickets. <\/li>\n<\/ul>\n<h2>Tabelas de servi\u00e7o<\/h2>\n<p>\nPara come\u00e7ar, um ERD esquem\u00e1tico simplificado, o que conseguimos no final:<br \/>\n<img decoding=\"async\" alt=\"Monitoramento de desempenho de consultas PostgreSQL. Parte 1 - Reportagem\" src=\"\/wp-content\/uploads\/2019\/04\/03d29f4d6932d470d9d88651cbf0c715.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<b class=\"spoiler_title\">Breve descri\u00e7\u00e3o das tabelas<\/b><b>endpoint <\/b> \u2014 host, ponto de conex\u00e3o com a inst\u00e2ncia<br \/>\n<b>database <\/b> \u2014 par\u00e2metros da base de dados<br \/>\n<b>pg_stat_history <\/b> \u2014 tabela hist\u00f3rica para armazenar instant\u00e2neas temporais da visualiza\u00e7\u00e3o do pg_stat_statements da base de dados alvo<br \/>\n<b>metric_glossary <\/b> \u2014 gloss\u00e1rio de m\u00e9tricas de desempenho<br \/>\n<b>metric_config <\/b> \u2014 configura\u00e7\u00e3o de m\u00e9tricas individuais<br \/>\n<b>metric <\/b> \u2014 m\u00e9trica espec\u00edfica para a consulta que est\u00e1 sendo monitorada<br \/>\n<b>metric_alert_history <\/b> \u2014 hist\u00f3rico de alertas de desempenho<br \/>\n<b>log_query <\/b> \u2014 tabela de servi\u00e7o para armazenar registros desmembrados do arquivo de log do PostgreSQL carregados da AWS<br \/>\n<b>baseline <\/b> \u2014 par\u00e2metros do per\u00edodo de tempo usado como base <br \/>\n<b>checkpoint <\/b> \u2014 configura\u00e7\u00e3o das m\u00e9tricas de verifica\u00e7\u00e3o do estado da base de dados<br \/>\n<b>checkpoint_alert_history <\/b> \u2014 hist\u00f3rico de alertas das m\u00e9tricas de verifica\u00e7\u00e3o do estado da base de dados<br \/>\n<b>pg_stat_db_queries <\/b> \u2014 tabela de servi\u00e7o de consultas ativas <br \/>\n<b>activity_log <\/b> \u2014 tabela de servi\u00e7o do log de atividade <br \/>\n<b>trap_oid <\/b> \u2014 tabela de servi\u00e7o de configura\u00e7\u00e3o de trap<\/p>\n<p><\/p>\n<h2>Etapa 1 \u2014 coletamos informa\u00e7\u00f5es estat\u00edsticas sobre o desempenho e obtemos relat\u00f3rios<\/h2>\n<p>\nPara armazenar informa\u00e7\u00f5es estat\u00edsticas, utiliza-se a tabela <b>pg_stat_history<\/b><br \/>\n<b class=\"spoiler_title\">Estrutura da tabela pg_stat_history<\/b><\/p>\n<pre>\n                                          Tabela \"public.pg_stat_history\"\n       Coluna        |            Tipo             |                          Modificadores\n---------------------+-----------------------------+-------------------------------------------\n id                  | inteiro                     | n\u00e3o nulo padr\u00e3o nextval('pg_stat_history_id_seq'::regclass)\n snapshot_timestamp  | timestamp sem fuso hor\u00e1rio |\n database_id         | inteiro                     |\n dbid                | oid                         |\n userid              | oid                         |\n queryid             | bigint                      |\n query               | texto                       |\n calls               | bigint                      |\n total_time          | precis\u00e3o dupla              |\n min_time            | precis\u00e3o dupla              |\n max_time            | precis\u00e3o dupla              |\n mean_time           | precis\u00e3o dupla              |\n stddev_time         | precis\u00e3o dupla              |\n rows                | bigint                      |\n shared_blks_hit     | bigint                      |\n shared_blks_read    | bigint                      |\n shared_blks_dirtied | bigint                      |\n shared_blks_written | bigint                      |\n local_blks_hit      | bigint                      |\n local_blks_read     | bigint                      |\n local_blks_dirtied  | bigint                      |\n local_blks_written  | bigint                      |\n temp_blks_read      | bigint                      |\n temp_blks_written   | bigint                      |\n blk_read_time       | precis\u00e3o dupla              |\n blk_write_time      | precis\u00e3o dupla              |\n baseline_id         | inteiro                     |\n\u00cdndices:\n    \"pg_stat_history_pkey\" CHAVE PRIM\u00c1RIA, btree (id)\n    \"database_idx\" btree (database_id)\n    \"queryid_idx\" btree (queryid)\n    \"snapshot_timestamp_idx\" btree (snapshot_timestamp)\nRestri\u00e7\u00f5es de chave estrangeira:\n    \"database_id_fk\" CHAVE ESTRANGEIRA (database_id) REFERENCES database(id) ON DELETE CASCADE<\/pre>\n<p>\nComo pode ser visto, a tabela representa apenas dados acumulados da vis\u00e3o <b>pg_stat_statements <\/b> na base de dados de destino.<\/p>\n<h3>O uso desta tabela \u00e9 muito simples<\/h3>\n<p>\n<b>pg_stat_history<\/b> representar\u00e1 a estat\u00edstica acumulada da execu\u00e7\u00e3o de consultas a cada hora. No in\u00edcio de cada hora, ap\u00f3s o preenchimento da tabela, as estat\u00edsticas <b>pg_stat_statements<\/b> s\u00e3o reiniciadas com o aux\u00edlio de <b>pg_stat_statements_reset()<\/b>.<br \/>\nNota: <i>as estat\u00edsticas s\u00e3o coletadas para consultas com dura\u00e7\u00e3o de execu\u00e7\u00e3o superior a 1 segundo.<\/i><br \/>\n<b class=\"spoiler_title\">Preenchimento da tabela pg_stat_history<\/b><\/p>\n<pre><code class=\"plaintext\">--pg_stat_history.sql\nCREATE OR REPLACE FUNCTION pg_stat_history( ) RETURNS boolean AS $$\nDECLARE\n  endpoint_rec record ;\n  database_rec record ;\n  pg_stat_snapshot record ;\n  current_snapshot_timestamp timestamp without time zone;\nBEGIN\n  current_snapshot_timestamp = date_trunc('minute',now());  \n  \n  FOR endpoint_rec IN SELECT * FROM endpoint \n  LOOP\n    FOR database_rec IN SELECT * FROM database WHERE endpoint_id = endpoint_rec.id \n\t  LOOP\n\t    \n\t\tRAISE NOTICE 'NOVA IMAGEM EST\u00c1 SENDO CRIADA';\n\t\t\n\t\t--Conectar ao DB alvo\t  \n\t    EXECUTE 'SELECT dblink_connect(''LINK1'',''host='||endpoint_rec.host||' dbname='||database_rec.name||' user=USER password=PASSWORD '')';\n \n        RAISE NOTICE 'host % e dbname % ',endpoint_rec.host,database_rec.name;\n\t\tRAISE NOTICE 'Criando a imagem de pg_stat_statements para o banco de dados %',database_rec.name;\n\t\t\n\t\tSELECT \n\t      *\n\t\tINTO \n\t\t  pg_stat_snapshot\n\t    FROM dblink('LINK1',\n\t      'SELECT \n\t       dbid , SUM(calls),SUM(total_time),SUM(rows) ,SUM(shared_blks_hit) ,SUM(shared_blks_read) ,SUM(shared_blks_dirtied) ,SUM(shared_blks_written) , \n           SUM(local_blks_hit) , SUM(local_blks_read) , SUM(local_blks_dirtied) , SUM(local_blks_written) , SUM(temp_blks_read) , SUM(temp_blks_written) , SUM(blk_read_time) , SUM(blk_write_time)\n\t       FROM pg_stat_statements WHERE dbid=(SELECT oid from pg_database where datname=current_database() ) \n\t\t   GROUP BY dbid\n  \t      '\n\t               )\n\t      AS t\n\t       ( dbid oid , calls bigint , \n  \t         total_time double precision , \n\t         rows bigint , shared_blks_hit bigint , shared_blks_read bigint ,shared_blks_dirtied bigint ,shared_blks_written\t bigint ,\n             local_blks_hit\t bigint ,local_blks_read bigint , local_blks_dirtied bigint ,local_blks_written bigint ,\n             temp_blks_read\t bigint ,temp_blks_written bigint ,\n             blk_read_time double precision , blk_write_time double precision\t  \n\t       );\n\t\t \n\t\tINSERT INTO pg_stat_history\n          ( \n\t\t    snapshot_timestamp  ,database_id  ,\n\t\t\tdbid , calls  ,total_time ,\n            rows ,shared_blks_hit  ,shared_blks_read  ,shared_blks_dirtied  ,shared_blks_written ,local_blks_hit , \t \n            local_blks_read,local_blks_dirtied,local_blks_written,temp_blks_read,temp_blks_written, \t\n            blk_read_time, blk_write_time \n\t\t  )\t\t  \n\t    VALUES\n\t      (\n\t       current_snapshot_timestamp ,\n\t\t   database_rec.id ,\n\t       pg_stat_snapshot.dbid ,pg_stat_snapshot.calls,\n\t       pg_stat_snapshot.total_time,\n\t       pg_stat_snapshot.rows ,pg_stat_snapshot.shared_blks_hit ,pg_stat_snapshot.shared_blks_read ,pg_stat_snapshot.shared_blks_dirtied ,pg_stat_snapshot.shared_blks_written , \n           pg_stat_snapshot.local_blks_hit , pg_stat_snapshot.local_blks_read , pg_stat_snapshot.local_blks_dirtied , pg_stat_snapshot.local_blks_written , \n\t       pg_stat_snapshot.temp_blks_read , pg_stat_snapshot.temp_blks_written , pg_stat_snapshot.blk_read_time , pg_stat_snapshot.blk_write_time \t   \n\t      );\t\t   \n\t\t  \n        RAISE NOTICE 'Criando a imagem de pg_stat_statements para consultas com min_time maior que 1000ms';\n\t\n        FOR pg_stat_snapshot IN\n          --Todas as consultas com max_time maior que 1000 ms\n\t      SELECT \n\t        *\n\t      FROM dblink('LINK1',\n\t        'SELECT \n\t         dbid , userid ,queryid,query,calls,total_time,min_time ,max_time,mean_time, stddev_time ,rows ,shared_blks_hit ,\n\t\t\t shared_blks_read ,shared_blks_dirtied ,shared_blks_written , \n             local_blks_hit , local_blks_read , local_blks_dirtied , \n\t\t\t local_blks_written , temp_blks_read , temp_blks_written , blk_read_time , \n\t\t\t blk_write_time\n\t         FROM pg_stat_statements \n\t\t\t WHERE dbid=(SELECT oid from pg_database where datname=current_database() AND min_time &gt;= 1000 ) \n  \t        '\n\n\t                  )\n\t        AS t\n\t         ( dbid oid , userid oid , queryid bigint ,query text , calls bigint , \n  \t           total_time double precision ,min_time double precision\t ,max_time double precision\t , mean_time double precision\t ,  stddev_time double precision\t , \n\t           rows bigint , shared_blks_hit bigint , shared_blks_read bigint ,shared_blks_dirtied bigint ,shared_blks_written\t bigint ,\n               local_blks_hit\t bigint ,local_blks_read bigint , local_blks_dirtied bigint ,local_blks_written bigint ,\n               temp_blks_read\t bigint ,temp_blks_written bigint ,\n               blk_read_time double precision , blk_write_time double precision\t  \n\t         )\n\t    LOOP\n\t\t  INSERT INTO pg_stat_history\n          ( \n\t\t    snapshot_timestamp  ,database_id  ,\n\t\t\tdbid ,userid  , queryid  , query  , calls  ,total_time ,min_time ,max_time ,mean_time ,stddev_time ,\n            rows ,shared_blks_hit  ,shared_blks_read  ,shared_blks_dirtied  ,shared_blks_written ,local_blks_hit , \t \n            local_blks_read,local_blks_dirtied,local_blks_written,temp_blks_read,temp_blks_written, \t\n            blk_read_time, blk_write_time \n\t\t  )\t\t  \n\t      VALUES\n\t      (\n\t       current_snapshot_timestamp ,\n\t\t   database_rec.id ,\n\t       pg_stat_snapshot.dbid ,pg_stat_snapshot.userid ,pg_stat_snapshot.queryid,pg_stat_snapshot.query,pg_stat_snapshot.calls,\n\t       pg_stat_snapshot.total_time,pg_stat_snapshot.min_time ,pg_stat_snapshot.max_time,pg_stat_snapshot.mean_time, pg_stat_snapshot.stddev_time ,\n\t       pg_stat_snapshot.rows ,pg_stat_snapshot.shared_blks_hit ,pg_stat_snapshot.shared_blks_read ,pg_stat_snapshot.shared_blks_dirtied ,pg_stat_snapshot.shared_blks_written , \n           pg_stat_snapshot.local_blks_hit , pg_stat_snapshot.local_blks_read , pg_stat_snapshot.local_blks_dirtied , pg_stat_snapshot.local_blks_written , \n\t       pg_stat_snapshot.temp_blks_read , pg_stat_snapshot.temp_blks_written , pg_stat_snapshot.blk_read_time , pg_stat_snapshot.blk_write_time \t   \n\t      );\n\t\t  \n        END LOOP;\n\n        PERFORM dblink_disconnect('LINK1');  \n\t\t\t\t\n\t  END LOOP ;--FOR database_rec IN SELECT * FROM database WHERE endpoint_id = endpoint_rec.id \n    \n  END LOOP;\n\nRETURN TRUE;  \nEND\n$$ LANGUAGE plpgsql;<\/code><\/pre>\n<p>Como resultado, ap\u00f3s um certo per\u00edodo de tempo na tabela <b>pg_stat_history<\/b> , teremos um conjunto de instant\u00e2neas do conte\u00fado da tabela <b>pg_stat_statements <\/b>do banco de dados alvo. <\/p>\n<h2>Relat\u00f3rios propriamente ditos<\/h2>\n<p>\nCom consultas simples, \u00e9 poss\u00edvel obter relat\u00f3rios bastante \u00fateis e interessantes.<\/p>\n<h2>Dados agregados para um intervalo de tempo espec\u00edfico<\/h2>\n<p><b class=\"spoiler_title\">Consulta<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  database_id , \n  SUM(calls) AS calls ,SUM(total_time)  AS total_time ,\n  SUM(rows) AS rows , SUM(shared_blks_hit)  AS shared_blks_hit,\n  SUM(shared_blks_read) AS shared_blks_read ,\n  SUM(shared_blks_dirtied) AS shared_blks_dirtied,\n  SUM(shared_blks_written) AS shared_blks_written , \n  SUM(local_blks_hit) AS local_blks_hit , \n  SUM(local_blks_read) AS local_blks_read , \n  SUM(local_blks_dirtied) AS local_blks_dirtied , \n  SUM(local_blks_written)  AS local_blks_written,\n  SUM(temp_blks_read) AS temp_blks_read, \n  SUM(temp_blks_written) temp_blks_written , \n  SUM(blk_read_time) AS blk_read_time , \n  SUM(blk_write_time) AS blk_write_time\nFROM \n  pg_stat_history\nWHERE \n  queryid IS NULL AND\n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT\nGROUP BY database_id ;<\/code><\/pre>\n<p><\/p>\n<h4>Tempo de DB<\/h4>\n<blockquote><p>to_char(interval '1 millisecond' * pg_total_stat_history_rec.total_time, 'HH24:MI:SS.MS')<\/p><\/blockquote>\n<p><\/p>\n<h4>Tempo de I\/O<\/h4>\n<blockquote><p>to_char(interval '1 millisecond' * (pg_total_stat_history_rec.blk_read_time + pg_total_stat_history_rec.blk_write_time), 'HH24:MI:SS.MS')<\/p><\/blockquote>\n<h3>TOP10 SQL por total_time<\/h3>\n<p><b class=\"spoiler_title\">Consulta<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  queryid , \n  SUM(calls) AS calls ,\n  SUM(total_time)  AS total_time  \t\nFROM \n  pg_stat_history\nWHERE \n  queryid IS NOT NULL AND \n  database_id = DATABASE_ID AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT \nGROUP BY queryid \nORDER BY 3 DESC \nLIMIT 10<\/code><\/pre>\n<pre>-------------------------------------------------------------------------------------\n| TOP10 SQL POR TEMPO DE EXECU\u00c7\u00c3O TOTAL\n|   #|    queryid|      calls|    calls %|                total_time (ms) |  dbtime %\n+----+-----------+-----------+-----------+--------------------------------+----------\n|   1|  821760255|          2|     .00001|00:03:23.141(    203141.681 ms.)|      5.42\n|   2| 4152624390|          2|     .00001|00:03:13.929(    193929.215 ms.)|      5.17\n|   3| 1484454471|          4|     .00001|00:02:09.129(    129129.057 ms.)|      3.44\n|   4|  655729273|          1|     .00000|00:02:01.869(    121869.981 ms.)|      3.25\n|   5| 2460318461|          1|     .00000|00:01:33.113(     93113.835 ms.)|      2.48\n|   6| 2194493487|          4|     .00001|00:00:17.377(     17377.868 ms.)|       .46\n|   7| 1053044345|          1|     .00000|00:00:06.156(      6156.352 ms.)|       .16\n|   8| 3644780286|          1|     .00000|00:00:01.063(      1063.830 ms.)|       .03\n<\/pre>\n<h4>TOP10 SQL por tempo total de I\/O<\/h4>\n<p><b class=\"spoiler_title\">Consulta<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  queryid , \n  SUM(calls) AS calls ,\n  SUM(blk_read_time + blk_write_time)  AS io_time\nFROM \n  pg_stat_history\nWHERE \n  queryid IS NOT NULL AND \n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT\nGROUP BY  queryid \nORDER BY 3 DESC \nLIMIT 10<\/code><\/pre>\n<pre>----------------------------------------------------------------------------------------\n| TOP10 SQL POR TEMPO TOTAL DE I\/O\n|   #|    queryid|      chamadas|    % de chamadas|                   Tempo de I\/O (ms)|% de tempo de I\/O do db\n+----+-----------+-----------+-----------+--------------------------------+-------------\n|   1| 4152624390|          2|     .00001|00:08:31.616(    511616.592 ms.)|        31.06\n|   2|  821760255|          2|     .00001|00:08:27.099(    507099.036 ms.)|        30.78\n|   3|  655729273|          1|     .00000|00:05:02.209(    302209.137 ms.)|        18.35\n|   4| 2460318461|          1|     .00000|00:04:05.981(    245981.117 ms.)|        14.93\n|   5| 1484454471|          4|     .00001|00:00:39.144(     39144.221 ms.)|         2.38\n|   6| 2194493487|          4|     .00001|00:00:18.182(     18182.816 ms.)|         1.10\n|   7| 1053044345|          1|     .00000|00:00:16.611(     16611.722 ms.)|         1.01\n|   8| 3644780286|          1|     .00000|00:00:00.436(       436.205 ms.)|          .03\n<\/pre>\n<h4>TOP10 SQL pelo tempo m\u00e1ximo de execu\u00e7\u00e3o<\/h4>\n<p><b class=\"spoiler_title\">Consulta<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  id AS snapshotid , \n  queryid , \n  snapshot_timestamp ,  \n  max_time \nFROM \n  pg_stat_history \nWHERE \n  queryid IS NOT NULL AND \n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT\nORDER BY 4 DESC \nLIMIT 10<\/code><\/pre>\n<p><\/p>\n<pre>-----------------------------------------------------------------------------------------\n| TOP10 SQL PELO TEMPO M\u00c1XIMO DE EXECU\u00c7\u00c3O\n|   #|          snapshot| snapshotID|    queryid|                           max_time (ms)\n+----+------------------+-----------+-----------+----------------------------------------\n|   1|  05.04.2019 01:03|       4169|  655729273|        00:02:01.869(    121869.981 ms.)\n|   2|  04.04.2019 17:00|       4153|  821760255|        00:01:41.570(    101570.841 ms.)\n|   3|  04.04.2019 16:00|       4146|  821760255|        00:01:41.570(    101570.841 ms.)\n|   4|  04.04.2019 16:00|       4144| 4152624390|        00:01:36.964(     96964.607 ms.)\n|   5|  04.04.2019 17:00|       4151| 4152624390|        00:01:36.964(     96964.607 ms.)\n|   6|  05.04.2019 10:00|       4188| 1484454471|        00:01:33.452(     93452.150 ms.)\n|   7|  04.04.2019 17:00|       4150| 2460318461|        00:01:33.113(     93113.835 ms.)\n|   8|  04.04.2019 15:00|       4140| 1484454471|        00:00:11.892(     11892.302 ms.)\n|   9|  04.04.2019 16:00|       4145| 1484454471|        00:00:11.892(     11892.302 ms.)\n|  10|  04.04.2019 17:00|       4152| 1484454471|        00:00:11.892(     11892.302 ms.)\n<\/pre>\n<h4>TOP10 SQL por leitura\/escrita de buffer COMPARTILHADO<\/h4>\n<p><b class=\"spoiler_title\">Consulta<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  id AS snapshotid , \n  queryid ,\n  snapshot_timestamp , \n  shared_blks_read , \n  shared_blks_written \nFROM \n  pg_stat_history\nWHERE \n  queryid IS NOT NULL AND \n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT AND\n  ( shared_blks_read &gt; 0 OR shared_blks_written &gt; 0 )\nORDER BY 4 DESC  , 5 DESC \nLIMIT 10<\/code><\/pre>\n<pre>--------------------------------------------------------------------------------------------\n| TOP10 SQL POR LEITURA\/GRAVA\u00c7\u00c3O DE BUFFER COMPARTILHADO\n|   #|          instant\u00e2neo| snapshotID|    queryid|   blocos compartilhados lidos|  blocos compartilhados escritos\n+----+------------------+-----------+-----------+---------------------+---------------------\n|   1|  04.04.2019 17:00|       4153|  821760255|               797308|                    0\n|   2|  04.04.2019 16:00|       4146|  821760255|               797308|                    0\n|   3|  05.04.2019 01:03|       4169|  655729273|               797158|                    0\n|   4|  04.04.2019 16:00|       4144| 4152624390|               756514|                    0\n|   5|  04.04.2019 17:00|       4151| 4152624390|               756514|                    0\n|   6|  04.04.2019 17:00|       4150| 2460318461|               734117|                    0\n|   7|  04.04.2019 17:00|       4155| 3644780286|                52973|                    0\n|   8|  05.04.2019 01:03|       4168| 1053044345|                52818|                    0\n|   9|  04.04.2019 15:00|       4141| 2194493487|                52813|                    0\n|  10|  04.04.2019 16:00|       4147| 2194493487|                52813|                    0\n--------------------------------------------------------------------------------------------\n<\/pre>\n<h4>Histograma de distribui\u00e7\u00e3o de consultas por tempo de execu\u00e7\u00e3o m\u00e1ximo<\/h4>\n<p><b class=\"spoiler_title\">Consultas<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT  \n  MIN(max_time) AS hist_min  , \n  MAX(max_time) AS hist_max , \n  (( MAX(max_time) - MIN(min_time) ) \/ hist_columns ) as hist_width\nFROM \n  pg_stat_history \nWHERE \n  queryid IS NOT NULL AND\n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT ;\n\nSELECT \n  SUM(calls) AS calls\nFROM \n  pg_stat_history \nWHERE \n  queryid IS NOT NULL AND\n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT AND \n  ( max_time &gt;= hist_current_min AND  max_time &lt; hist_current_max ) ;\n<\/code><\/pre>\n<pre>|-----------------------------------------------------------------------------------------------\n| HISTOGRAMA DE TEMPO M\u00c1XIMO\n| TOTAL DE CHAMADAS : 33851920\n| TEMPO M\u00cdNIMO  : 00:00:01.063\n| TEMPO M\u00c1XIMO  : 00:02:01.869\n---------------------------------------------------------------------------------\n|                      dura\u00e7\u00e3o m\u00ednima|                      dura\u00e7\u00e3o m\u00e1xima|     chamadas\n+----------------------------------+----------------------------------+----------\n| 00:00:01.063(      1063.830 ms.) | 00:00:13.144(     13144.445 ms.) | 9\n| 00:00:13.144(     13144.445 ms.) | 00:00:25.225(     25225.060 ms.) | 0\n| 00:00:25.225(     25225.060 ms.) | 00:00:37.305(     37305.675 ms.) | 0\n| 00:00:37.305(     37305.675 ms.) | 00:00:49.386(     49386.290 ms.) | 0\n| 00:00:49.386(     49386.290 ms.) | 00:01:01.466(     61466.906 ms.) | 0\n| 00:01:01.466(     61466.906 ms.) | 00:01:13.547(     73547.521 ms.) | 0\n| 00:01:13.547(     73547.521 ms.) | 00:01:25.628(     85628.136 ms.) | 0\n| 00:01:25.628(     85628.136 ms.) | 00:01:37.708(     97708.751 ms.) | 4\n| 00:01:37.708(     97708.751 ms.) | 00:01:49.789(    109789.366 ms.) | 2\n| 00:01:49.789(    109789.366 ms.) | 00:02:01.869(    121869.981 ms.) | 0\n<\/pre>\n<h4>TOP10 Instant\u00e2neas por Consulta por Segundo<\/h4>\n<p><b class=\"spoiler_title\">Consultas<\/b><\/p>\n<pre><code class=\"plaintext\">--pg_qps.sql\n--Calcular Consultas Por Segundo \nCREATE OR REPLACE FUNCTION pg_qps( pg_stat_history_id integer ) RETURNS double precision AS $$\nDECLARE\n pg_stat_history_rec record ;\n prev_pg_stat_history_id integer ;\n prev_pg_stat_history_rec record;\n total_seconds double precision ;\n result double precision;\nBEGIN \n  result = 0 ;\n  \n  SELECT *\n  INTO pg_stat_history_rec\n  FROM \n    pg_stat_history\n  WHERE id = pg_stat_history_id ;\n\n  IF pg_stat_history_rec.snapshot_timestamp IS NULL \n  THEN\n    RAISE EXCEPTION 'ERRO - pg_stat_history n\u00e3o encontrado para id = %',pg_stat_history_id;\n  END IF ;  \n  \n --RAISE NOTICE 'pg_stat_history_id = % , snapshot_timestamp = %', pg_stat_history_id , \n pg_stat_history_rec.snapshot_timestamp ;\n  \n  SELECT \n    MAX(id)   \n  INTO\n    prev_pg_stat_history_id\n  FROM\n    pg_stat_history\n  WHERE \n    database_id = pg_stat_history_rec.database_id AND\n\tqueryid IS NULL AND\n\tid  0 \n  THEN\n    result = pg_stat_history_rec.calls \/ total_seconds ;\n  ELSE\n   result = 0 ; \n  END IF;\n   \n RETURN result ;\nEND\n$$ LANGUAGE plpgsql;\n\n\nSELECT \n  id , \n  snapshot_timestamp ,\n  calls , \t\n  total_time , \n  ( select pg_qps( id )) AS QPS ,\n  blk_read_time ,\n  blk_write_time\nFROM \n  pg_stat_history\nWHERE \n  queryid IS NULL AND \n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT AND\n  ( select pg_qps( id )) IS NOT NULL \nORDER BY 5 DESC \nLIMIT 10\n<\/code><\/pre>\n<pre>|-----------------------------------------------------------------------------------------------\n| TOP10 Capturas ordenadas por n\u00fameros de QueryPerSeconds\n-----------------------------------------------------------------------------------------------------------------------------------------------\n|    #|          captura| snapshotID|      chamadas|                      tempo total db|        QPS|                          tempo I\/O| percentual de tempo I\/O%\n+-----+------------------+-----------+-----------+----------------------------------+-----------+----------------------------------+-----------\n|    1|  04.04.2019 20:04|       4161|    5758631|  00:06:30.513(    390513.926 ms.)|   1573.396|  00:00:01.470(      1470.110 ms.)|       .376\n|    2|  04.04.2019 17:00|       4149|    3529197|  00:11:48.830(    708830.618 ms.)|    980.332|  00:12:47.834(    767834.052 ms.)|    108.324\n|    3|  04.04.2019 16:00|       4143|    3525360|  00:10:13.492(    613492.351 ms.)|    979.267|  00:08:41.396(    521396.555 ms.)|     84.988\n|    4|  04.04.2019 21:03|       4163|    2781536|  00:03:06.470(    186470.979 ms.)|    785.745|  00:00:00.249(       249.865 ms.)|       .134\n|    5|  04.04.2019 19:03|       4159|    2890362|  00:03:16.784(    196784.755 ms.)|    776.979|  00:00:01.441(      1441.386 ms.)|       .732\n|    6|  04.04.2019 14:00|       4137|    2397326|  00:04:43.033(    283033.854 ms.)|    665.924|  00:00:00.024(        24.505 ms.)|       .009\n|    7|  04.04.2019 15:00|       4139|    2394416|  00:04:51.435(    291435.010 ms.)|    665.116|  00:00:12.025(     12025.895 ms.)|      4.126\n|    8|  04.04.2019 13:00|       4135|    2373043|  00:04:26.791(    266791.988 ms.)|    659.179|  00:00:00.064(        64.261 ms.)|       .024\n|    9|  05.04.2019 01:03|       4167|    4387191|  00:06:51.380(    411380.293 ms.)|    609.332|  00:05:18.847(    318847.407 ms.)|     77.507\n|   10|  04.04.2019 18:01|       4157|    1145596|  00:01:19.217(     79217.372 ms.)|    313.004|  00:00:01.319(      1319.676 ms.)|      1.666\n<\/pre>\n<h4>Hist\u00f3rico de Execu\u00e7\u00e3o Hor\u00e1ria com QueryPerSeconds e Tempo I\/O<\/h4>\n<p><b class=\"spoiler_title\">Consulta<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  id , \n  snapshot_timestamp ,\n  chamadas , \t\n  tempo_total , \n  ( select pg_qps( id )) AS QPS ,\n  blk_read_time ,\n  blk_write_time\nFROM \n  pg_stat_history\nWHERE \n  queryid IS NULL AND \n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT\nORDER BY 2\n<\/code><\/pre>\n<pre>|-----------------------------------------------------------------------------------------------\n| HIST\u00d3RICO DE EXECU\u00c7\u00c3O POR HORA COM QueryPerSeconds e Tempo I\/O\n-----------------------------------------------------------------------------------------------------------------------------------------------\n| HIST\u00d3RICO DE CONSULTAS POR SEGUNDO\n|    #|          instant\u00e2neo| snapshotID|      chamadas|                      total dbtime|        QPS|                          tempo I\/O| % do tempo I\/O\n+-----+------------------+-----------+-----------+----------------------------------+-----------+----------------------------------+-----------\n|    1|  04.04.2019 11:00|       4131|       3747|  00:00:00.835(       835.374 ms.)|      1.041|  00:00:00.000(          .000 ms.)|       .000\n|    2|  04.04.2019 12:00|       4133|    1002722|  00:01:52.419(    112419.376 ms.)|    278.534|  00:00:00.149(       149.105 ms.)|       .133\n|    3|  04.04.2019 13:00|       4135|    2373043|  00:04:26.791(    266791.988 ms.)|    659.179|  00:00:00.064(        64.261 ms.)|       .024\n|    4|  04.04.2019 14:00|       4137|    2397326|  00:04:43.033(    283033.854 ms.)|    665.924|  00:00:00.024(        24.505 ms.)|       .009\n|    5|  04.04.2019 15:00|       4139|    2394416|  00:04:51.435(    291435.010 ms.)|    665.116|  00:00:12.025(     12025.895 ms.)|      4.126\n|    6|  04.04.2019 16:00|       4143|    3525360|  00:10:13.492(    613492.351 ms.)|    979.267|  00:08:41.396(    521396.555 ms.)|     84.988\n|    7|  04.04.2019 17:00|       4149|    3529197|  00:11:48.830(    708830.618 ms.)|    980.332|  00:12:47.834(    767834.052 ms.)|    108.324\n|    8|  04.04.2019 18:01|       4157|    1145596|  00:01:19.217(     79217.372 ms.)|    313.004|  00:00:01.319(      1319.676 ms.)|      1.666\n|    9|  04.04.2019 19:03|       4159|    2890362|  00:03:16.784(    196784.755 ms.)|    776.979|  00:00:01.441(      1441.386 ms.)|       .732\n|   10|  04.04.2019 20:04|       4161|    5758631|  00:06:30.513(    390513.926 ms.)|   1573.396|  00:00:01.470(      1470.110 ms.)|       .376\n|   11|  04.04.2019 21:03|       4163|    2781536|  00:03:06.470(    186470.979 ms.)|    785.745|  00:00:00.249(       249.865 ms.)|       .134\n|   12|  04.04.2019 23:03|       4165|    1443155|  00:01:34.467(     94467.539 ms.)|    200.438|  00:00:00.015(        15.287 ms.)|       .016\n|   13|  05.04.2019 01:03|       4167|    4387191|  00:06:51.380(    411380.293 ms.)|    609.332|  00:05:18.847(    318847.407 ms.)|     77.507\n|   14|  05.04.2019 02:03|       4171|     189852|  00:00:10.989(     10989.899 ms.)|     52.737|  00:00:00.539(       539.110 ms.)|      4.906\n|   15|  05.04.2019 03:01|       4173|       3627|  00:00:00.103(       103.000 ms.)|      1.042|  00:00:00.004(         4.131 ms.)|      4.010\n|   16|  05.04.2019 04:00|       4175|       3627|  00:00:00.085(        85.235 ms.)|      1.025|  00:00:00.003(         3.811 ms.)|      4.471\n|   17|  05.04.2019 05:00|       4177|       3747|  00:00:00.849(       849.454 ms.)|      1.041|  00:00:00.006(         6.124 ms.)|       .721\n|   18|  05.04.2019 06:00|       4179|       3747|  00:00:00.849(       849.561 ms.)|      1.041|  00:00:00.000(          .051 ms.)|       .006\n|   19|  05.04.2019 07:00|       4181|       3747|  00:00:00.839(       839.416 ms.)|      1.041|  00:00:00.000(          .062 ms.)|       .007\n|   20|  05.04.2019 08:00|       4183|       3747|  00:00:00.846(       846.382 ms.)|      1.041|  00:00:00.000(          .007 ms.)|       .001\n|   21|  05.04.2019 09:00|       4185|       3747|  00:00:00.855(       855.426 ms.)|      1.041|  00:00:00.000(          .065 ms.)|       .008\n|   22|  05.04.2019 10:00|       4187|       3797|  00:01:40.150(    100150.165 ms.)|      1.055|  00:00:21.845(     21845.217 ms.)|     21.812\n<\/pre>\n<h4>Texto de todas as consultas SQL<\/h4>\n<p><b class=\"spoiler_title\">Consulta<\/b><\/p>\n<pre><code class=\"plaintext\">SELECIONE\n  queryid,\n  query\nFROM\n  pg_stat_history\nWHERE\n  queryid N\u00c3O \u00c9 NULO E\n  database_id = DATABASE_ID E\n  snapshot_timestamp ENTRE BEGIN_TIMEPOINT E END_TIMEPOINT\nAGRUPAR POR queryid, query\n<\/code><\/pre>\n<h2>Resultado<\/h2>\n<p>\nComo pode ser visto, utilizando recursos bastante simples, \u00e9 poss\u00edvel obter uma quantidade consider\u00e1vel de informa\u00e7\u00f5es \u00fateis sobre a carga e o estado do banco de dados. <\/p>\n<p><b>Observa\u00e7\u00e3o:<\/b>Se nos comandos registrarmos o queryid, teremos um hist\u00f3rico de consultas separadas (com o objetivo de economizar espa\u00e7o, relat\u00f3rios para consultas separadas foram omitidos).<\/p>\n<p>Assim, os dados estat\u00edsticos sobre o desempenho das consultas est\u00e3o dispon\u00edveis e sendo coletados.<br \/>\nA primeira etapa \"coleta de dados estat\u00edsticos\" foi conclu\u00edda.<\/p>\n<p>Podemos passar para a segunda etapa - \"configura\u00e7\u00e3o de m\u00e9tricas de desempenho\".<br \/>\n<img decoding=\"async\" alt=\"Monitoramento de desempenho de consultas PostgreSQL. Parte 1 - Reportagem\" src=\"\/wp-content\/uploads\/2019\/04\/a893e49280d4cb425e4667a5c51d2397.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Mas isso j\u00e1 \u00e9 uma hist\u00f3ria completamente diferente.<\/b><\/p>\n<p><i>Continua\u2026<\/i><br \/>\n<br \/>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/icl_services\/blog\/446734\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u2014 \u0432 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 \u0441 \u043b\u0430\u0442\u044b\u043d\u0438 \u2014 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0435\u043d\u043d\u044b\u0439. \u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0451. (\u0441) \u0420.\u0414\u0438\u0437\u0435\u043b\u044c. \u042d\u043f\u0438\u0433\u0440\u0430\u0444\u044b. \u0418\u043b\u0438 \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043e \u0442\u043e\u043c, \u0437\u0430\u0447\u0435\u043c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0443 \u0431\u0430\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u0442\u044c \u0441\u0432\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0441\u043a\u043e\u0435 \u043f\u0440\u043e\u0448\u043b\u043e\u0435. \u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435 \u0412\u0441\u0435 \u0438\u043c\u0435\u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b. \u0421\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b. \u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u0438\u0447\u043d\u043e\u0435 \u043c\u043d\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0430. Disclaimer of warranties: \u0432 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0441\u0442\u0430\u0442\u0435\u0439 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446 \u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24168,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-32353","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.5 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u2014 \u0432 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 \u0441 \u043b\u0430\u0442\u044b\u043d\u0438 \u2014 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0435\u043d\u043d\u044b\u0439. \u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0451. (\u0441) \u0420.\u0414\u0438\u0437\u0435\u043b\u044c. \u042d\u043f\u0438\u0433\u0440\u0430\u0444\u044b.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.5\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 PostgreSQL. \u0427\u0430\u0441\u0442\u044c 1 \u2014 \u0440\u0435\u043f\u043e\u0440\u0442\u0438\u043d\u0433 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u2014 \u0432 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 \u0441 \u043b\u0430\u0442\u044b\u043d\u0438 \u2014 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0435\u043d\u043d\u044b\u0439. \u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0451. (\u0441) \u0420.\u0414\u0438\u0437\u0435\u043b\u044c. \u042d\u043f\u0438\u0433\u0440\u0430\u0444\u044b.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:46:32+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:46:32+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Monitoramento de desempenho de consultas PostgreSQL. Parte 1 \u2014 relat\u00f3rios | ProHoster","description":"Engenheiro \u2014 em latim \u2014 significa inspirado. O engenheiro pode tudo. (c) R. Diesel. Ep\u00edgrafes.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 PostgreSQL. \u0427\u0430\u0441\u0442\u044c 1 \u2014 \u0440\u0435\u043f\u043e\u0440\u0442\u0438\u043d\u0433 | ProHoster","og:description":"\u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u2014 \u0432 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 \u0441 \u043b\u0430\u0442\u044b\u043d\u0438 \u2014 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0435\u043d\u043d\u044b\u0439. \u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0451. (\u0441) \u0420.\u0414\u0438\u0437\u0435\u043b\u044c. \u042d\u043f\u0438\u0433\u0440\u0430\u0444\u044b.","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:46:32+00:00","article:modified_time":"2019-10-31T18:46:32+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"32353","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 10:28:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:13:42","updated":"2026-01-21 10:28:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/32353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=32353"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/32353\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/24168"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=32353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=32353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=32353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}