{"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\/nl\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting","title":{"rendered":"Monitoring van de prestaties van PostgreSQL-queries. Deel 1 - rapportage","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Ingenieur is in het Latijn ge\u00efnspireerd.<br \/>\nEen ingenieur kan alles. (c) R.Diesel.<br \/>\n<i>Epigrafen.<\/i><br \/>\n<img decoding=\"async\" alt=\"Monitoring van de prestaties van PostgreSQL-queries. Deel 1 - rapportage\" src=\"\/wp-content\/uploads\/2019\/04\/9a2640267ea05006b94e03642b864ddc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Of het verhaal over waarom een database-administrator zijn programmeerachtergrond moet herinneren. <\/i><\/p>\n<h2>Voorwoord<\/h2>\n<p>\nAlle namen zijn gewijzigd. Toevalligheden zijn willekeurig. Het materiaal is uitsluitend de persoonlijke mening van de auteur.<\/p>\n<blockquote><p><b>Disclaimer van garanties:<\/b> <i>in de geplande serie artikelen zal er geen gedetailleerde en nauwkeurige beschrijving zijn van de gebruikte tabellen en scripts. Materialen kunnen niet meteen 'AS IS' worden gebruikt. <br \/>\nTen eerste vanwege de grote hoeveelheid materiaal, <br \/>\nten tweede vanwege de specificiteit in de productieomgeving van de echte klant. <br \/>\nDaarom zullen de artikelen alleen idee\u00ebn en beschrijvingen in de meest algemene zin bevatten. <br \/>\nMisschien groeit het systeem in de toekomst uit tot een niveau waarop het op GitHub kan worden geplaatst, en misschien ook niet. De tijd zal dat leren.<\/i><\/p><\/blockquote>\n<p>\nBegin van het verhaal - \"<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/icl_services\/blog\/446314\/\">Weet je nog hoe het begon<\/a><\/noindex>\u00bb.<br \/>\nWat er als resultaat is ontstaan, in de meest algemene lijnen - \"<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/444988\/\">Cloudflare heeft zijn eigen VPN-service gelanceerd op basis van de 1.1.1.1-app voor mobiele apparaten<\/a><\/noindex>\u00bb<\/p>\n<h2>Waarom is dit allemaal voor mij?<\/h2>\n<p>\nNou, ten eerste om zelf niets te vergeten, als ik met pensioen ben en terugdenk aan die glorieuze dagen. <br \/>\nTen tweede om het geschrevene te systematiseren. Want soms begin ik zelf in de war te raken en vergeet ik bepaalde delen. <\/p>\n<p>En het belangrijkste - wie weet, misschien kan het iemand helpen en ervoor zorgen dat ze niet de fiets opnieuw uitvinden en niet op dezelfde rake botsten. Met andere woorden, om hun karma (niet habr's) te verbeteren. Want het waardevolste in deze wereld zijn idee\u00ebn. Het belangrijkste is om een idee te vinden. En het idee in werkelijkheid omzetten is al een puur technische kwestie.<\/p>\n<p>Laten we dus langzaam beginnen\u2026<\/p>\n<h2>Probleemstelling.<\/h2>\n<p><\/p>\n<h3>Er is: <\/h3>\n<p>\nPostgreSQL-database (10.5), gemengde belasting (OLTP+DSS), gemiddelde-lage belasting, gelegen in de AWS-cloud. <br \/>\nDatabase-monitoring ontbreekt, infrastructuurmonitoring wordt geleverd via de standaardmiddelen van AWS in minimale configuratie.<\/p>\n<h3>Benodigd:<\/h3>\n<p>\nDe prestaties en de toestand van de database monitoren, en de initi\u00eble informatie voor het optimaliseren van zware databasequery's vinden en hebben.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Korte inleiding of analyse van oplossingsvarianten<\/h2>\n<p>\nLaten we beginnen met het onderzoeken van de oplossingsvarianten vanuit het perspectief van een vergelijkende analyse van de voordelen en nadelen voor de ingenieur, terwijl het management zich maar moet bezighouden met de voordelen en kosten zoals het hoort volgens het personeelsregister.<\/p>\n<h3>Variant 1 - \"Werken op aanvraag\"<\/h3>\n<p>\nWe leave everything as it is. If the client is not satisfied with something in the performance of the database or application, they will notify the DBA engineers by email or by creating an incident in the ticketing system. <br \/>\nThe engineer, upon receiving the notification, will investigate the problem, propose a solution, or postpone the issue, hoping that it resolves itself, and anyway, it will soon be forgotten.<br \/>\n<b class=\"spoiler_title\">Cookies and donuts, bruises and bumps<\/b><b>Cookies and donuts:<\/b><br \/>\n1. Nothing extra needs to be done<br \/>\n2. There is always a possibility to excuse oneself and slack off. <br \/>\n3. A lot of time can be spent at one's own discretion.<br \/>\n<b>Bruises and bumps:<\/b><br \/>\n1. Sooner or later, the client will ponder the essence of existence and universal justice in this world, and once again, they will ask themselves the question \u2014 why am I paying them my money? The outcome is always the same \u2014 the only question is when the client will get bored and wave goodbye. And the feeder will empty. It's sad.<br \/>\n2. The engineer's development is zero.<br \/>\n3. Difficulties in planning work and loading <\/p>\n<h3>Option 2 - \"We dance with tambourines, pushing and shoeing\"<\/h3>\n<p>\n<b>Point 1<\/b>-Why do we need a monitoring system? We will get everything through requests. We launch a bunch of various requests to the data dictionary and dynamic views, enable various counters, compile everything into tables, periodically, sort of, analyze the lists and tables. As a result, we have beautiful or not so beautiful graphics, tables, reports. The main thing is to have more, more.<br \/>\n<b>Point 2<\/b>-We generate activity - we start analyzing all of this.<br \/>\n<b>Point 3<\/b>-We prepare some document, simply calling this document - \"how to organize our database.\"<br \/>\n<b>Point 4<\/b>-The client, seeing all this magnificence of graphs and numbers, remains in a childlike naive confidence - now everything will work, soon. And easily and painlessly, they part with their financial resources. Management is also confident - our engineers are doing great. Load is at maximum. <br \/>\n<b>Point 5<\/b>-Regularly repeat Point 1.<br \/>\n<b class=\"spoiler_title\">Cookies and donuts, bruises and bumps<\/b><b>Cookies and donuts: <\/b><br \/>\n1. The life of managers and engineers is simple, predictable, and filled with activity. Everything is buzzing, everyone is busy. <br \/>\n2. The client's life is also not bad - they are always sure that they just need to be a little more patient and everything will be fine. It doesn\u2019t get better, well, what can you do - this world is unfair, next life - luckier.<br \/>\n<b>Bruises and bumps:<\/b><br \/>\n1. Op een gegeven moment zal er wel een snellere aanbieder van een vergelijkbare dienst komen die hetzelfde doet, maar iets goedkoper is. En als het resultaat hetzelfde is, waarom meer betalen? Dit zal opnieuw leiden tot het verdwijnen van de geldstroom.<br \/>\n2. Dit is saai. Zoals elke weinig zinnige activiteit.<br \/>\n3. Zoals in de vorige variant \u2014 er is geen ontwikkeling. Maar voor de engineer is het minpunt dat, in tegenstelling tot de eerste variant, hier constant een database moet worden gegenereerd. En dat kost tijd. Tijd die je beter aan jezelf kunt besteden. Want als je niet voor jezelf zorgt, doet niemand het.<\/p>\n<h3>Variant 3 - Je hoeft het wiel niet opnieuw uit te vinden, je moet het kopen en gaan fietsen.<\/h3>\n<p>\nIngenieurs van andere bedrijven eten niet voor niets pizza met bier (oh, de glorieuze tijden in Sint-Petersburg in de jaren '90). Laten we gebruikmaken van monitoring systemen die zijn gemaakt, verfijnd en werken, en die, laten we wel wezen, eigenlijk nuttig zijn (tenzij voor hun makers).<br \/>\n<b class=\"spoiler_title\">Cookies and donuts, bruises and bumps<\/b><b>Cookies and donuts:<\/b><br \/>\n1. Je hoeft geen tijd te besteden aan het verzinnen van wat al is uitgevonden. Neem het en gebruik het.<br \/>\n2. Monitoring systemen worden niet door domme mensen geschreven en ze zijn natuurlijk nuttig.<br \/>\n3. Werkende monitoring systemen bieden doorgaans nuttige gefilterde informatie. <br \/>\n<b>Bruises and bumps:<\/b><br \/>\n1. De engineer is in dit geval geen engineer, maar gewoon een gebruiker van iemands product. Of een gebruiker.<br \/>\n2. De opdrachtgever moet worden overtuigd van de noodzaak om iets te kopen waar hij eigenlijk niet in ge\u00efnteresseerd is, en dat moet hij ook niet zijn. Bovendien is het budget voor het jaar goedgekeurd en zal dit niet veranderen. Daarna moet er een aparte bron worden toegewezen, afgestemd op het specifieke systeem. Dus eerst moet je betalen, betalen en nog eens betalen. En de opdrachtgever is gierig. Dit is de norm van het leven.<\/p>\n<h2>Wat te doen - Tsjernysjovski? Jouw vraag is zeer relevant. (c)<\/h2>\n<p>\nIn dit specifieke geval en de huidige situatie kunnen we het iets anders aanpakken \u2014 <b>laten we ons eigen monitoring systeem maken. <\/b><br \/>\n<img decoding=\"async\" alt=\"Monitoring van de prestaties van PostgreSQL-queries. Deel 1 - rapportage\" src=\"\/wp-content\/uploads\/2019\/04\/b59a3ad9e16b68c0fbc962a61d571c52.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nNou, niet echt een systeem in de volle zin van het woord, dat is een te talige en zelfingenomen uitspraak, maar laten we proberen het onszelf iets gemakkelijker te maken en meer informatie te verzamelen voor het oplossen van prestatie-incidenten. Zodat we niet in de situatie komen \u2014 \u201cga daarheen, weet niet waar, vind dat, weet niet wat\u201d.<\/p>\n<h4>Wat zijn de voordelen en nadelen van deze optie:<\/h4>\n<p><b>Voordelen:<\/b><br \/>\n1. Dit is interessant. In ieder geval interessanter dan constante \u2018shrink datafile, alter tablespace, etc.\u2019 <br \/>\n2. Dit zijn nieuwe vaardigheden en een nieuwe ontwikkeling. Wat op de lange termijn vroeg of laat de verdiende beloningen en lekkernijen zal opleveren.<br \/>\n<b>Nadelen:<\/b><br \/>\n1. We moeten aan de bak. Veel werken. <br \/>\n2. We moeten regelmatig de betekenis en de vooruitzichten van alle activiteiten uitleggen.<br \/>\n3. We moeten ergens voor opofferen, omdat de enige beschikbare bron voor een ingenieur \u2014 tijd \u2014 beperkt is door het universum. <br \/>\n<b>4. Het ergste en het meest onaangename<\/b> \u2014 kan resulteren in iets als 'Geen muis, geen kikker, maar een onbekend beestje'.<\/p>\n<p><b>Wie niet waagt, die niet wint.<\/b><br \/>\nDus \u2014 het interessantste begint nu.<\/p>\n<h2>Het algemene idee \u2014 schematisch.<\/h2>\n<p>\n<img decoding=\"async\" alt=\"Monitoring van de prestaties van PostgreSQL-queries. Deel 1 - rapportage\" src=\"\/wp-content\/uploads\/2019\/04\/d1ae2ddc1d4c43353fe93eebdaa8b81a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n(<i>De illustratie is afkomstig uit een artikel.<\/i> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/444988\/\">Cloudflare heeft zijn eigen VPN-service gelanceerd op basis van de 1.1.1.1-app voor mobiele apparaten<\/a><\/noindex>\u00bb)<\/p>\n<p>Uitleg:<\/p>\n<ul>\n<li> In de doeldatabase wordt de standaarduitbreiding PostgreSQL \u2014 \u201cpg_stat_statements\u201d \u2014 ge\u00efnstalleerd. <\/li>\n<li>In de monitoringdatabase cre\u00ebren we een set service-tabellen voor het opslaan van de geschiedenis van pg_stat_statements in de beginfase en voor het instellen van metrics en monitoring in de toekomst.<\/li>\n<li> Op de monitoringhost cre\u00ebren we een set bash-scripts, waaronder voor het genereren van incidenten in het ticketingssysteem. <\/li>\n<\/ul>\n<h2>Service-tabellen<\/h2>\n<p>\nVoorlopig een schematisch vereenvoudigd ERD, wat hebben we uiteindelijk gekregen:<br \/>\n<img decoding=\"async\" alt=\"Monitoring van de prestaties van PostgreSQL-queries. Deel 1 - rapportage\" src=\"\/wp-content\/uploads\/2019\/04\/03d29f4d6932d470d9d88651cbf0c715.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<b class=\"spoiler_title\">Korte beschrijving van de tabellen<\/b><b>om verschillende typen datastromen binnen \u00e9\u00e9n apparaat te scheiden. <\/b> \u2014 host, verbindingspunt voor de instantie<br \/>\n<b>database <\/b> \u2014 databaseparameters<br \/>\n<b>pg_stat_history <\/b> \u2014 historische tabel voor het opslaan van tijdsnapshotweergaves van pg_stat_statements van de doel-database<br \/>\n<b>metric_glossary <\/b> \u2014 woordenboek van prestatiemetrics<br \/>\n<b>metric_config <\/b> \u2014 configuratie van afzonderlijke metrics<br \/>\n<b>metric <\/b> \u2014 specifieke metric voor de verzoeken die gemonitord worden<br \/>\n<b>metric_alert_history <\/b> \u2014 geschiedenis van prestatiealerts<br \/>\n<b>log_query <\/b> \u2014 hulptable voor het opslaan van ontlede records uit de logbestanden van PostgreSQL die worden gedownload van AWS<br \/>\n<b>baseline <\/b> \u2014 parameters van de tijdsperiode die als basis wordt gebruikt <br \/>\n<b>checkpoint <\/b> \u2014 configuratie van metrics voor database-statuscontroles<br \/>\n<b>checkpoint_alert_history <\/b> \u2014 geschiedenis van alerts voor metrics van database-statuscontroles<br \/>\n<b>pg_stat_db_queries <\/b> \u2014 hulptable voor actieve verzoeken <br \/>\n<b>activity_log <\/b> \u2014 hulptable voor het logboek van activiteit <br \/>\n<b>trap_oid <\/b> \u2014 hulptable voor trapconfiguratie<\/p>\n<p><\/p>\n<h2>Stap 1 \u2014 we verzamelen statistische informatie over prestaties en genereren rapporten.<\/h2>\n<p>\nDe tabel wordt gebruikt voor het opslaan van statistische informatie. <b>pg_stat_history<\/b><br \/>\n<b class=\"spoiler_title\">Structuur van de tabel pg_stat_history<\/b><\/p>\n<pre>\n                                          Tabel \"public.pg_stat_history\"\n       Kolom         |            Type             |                          Wijzigingen\n---------------------+-----------------------------+-------------------------------------------\n id                  | integer                     | niet null standaard nextval('pg_stat_history_id_seq'::regclass)\n snapshot_timestamp  | timestamp zonder tijdzone |\n database_id         | integer                     |\n dbid                | oid                         |\n userid              | oid                         |\n queryid             | bigint                      |\n query               | tekst                       |\n calls               | bigint                      |\n total_time          | dubbele precisie            |\n min_time            | dubbele precisie            |\n max_time            | dubbele precisie            |\n mean_time           | dubbele precisie            |\n stddev_time         | dubbele precisie            |\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       | dubbele precisie            |\n blk_write_time      | dubbele precisie            |\n baseline_id         | integer                     |\nIndexes:\n    \"pg_stat_history_pkey\" PRIMARY KEY, btree (id)\n    \"database_idx\" btree (database_id)\n    \"queryid_idx\" btree (queryid)\n    \"snapshot_timestamp_idx\" btree (snapshot_timestamp)\nForeign-key constraints:\n    \"database_id_fk\" FOREIGN KEY (database_id) REFERENCES database(id) ON DELETE CASCADE<\/pre>\n<p>\nZoals blijkt, vertegenwoordigt de tabel slechts cumulatieve gegevens van de weergave <b>pg_stat_statements <\/b> in de doeldatabase.<\/p>\n<h3>Het gebruik van deze tabel is heel eenvoudig<\/h3>\n<p>\n<b>pg_stat_history<\/b> het zal de verzamelde statistieken van query-uitvoeringen per uur weergeven. Aan het begin van elk uur, na het vullen van de tabel, worden de statistieken <b>pg_stat_statements<\/b> gereset met behulp van <b>pg_stat_statements_reset()<\/b>.<br \/>\nOpmerking: <i>statistieken worden verzameld voor queries met een uitvoeringstijd van meer dan 1 seconde.<\/i><br \/>\n<b class=\"spoiler_title\">Vullen van de tabel 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 'ER WORDT EEN NIEUWE MOMENTOPNAME AANGEMAAKT';\n\t\t\n\t\t--Verbind met de doeldatabase\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 % en dbname % ',endpoint_rec.host,database_rec.name;\n\t\tRAISE NOTICE 'Een momentopname van pg_stat_statements voor database % wordt aangemaakt',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, \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 'Een momentopname van pg_stat_statements voor vragen met min_time meer dan 1000ms wordt aangemaakt';\n\t\n        FOR pg_stat_snapshot IN\n          --Alle vragen met max_time groter dan 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, \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>Als resultaat, na een bepaalde periode in de tabel <b>pg_stat_history<\/b> hebben we een set van inhoudsopnamen van de tabel <b>pg_stat_statements <\/b>van de doel-database. <\/p>\n<h2>Eigenlijk rapporteren<\/h2>\n<p>\nMet eenvoudige queries kunnen we vrij nuttige en interessante rapporten genereren.<\/p>\n<h2>Geaggregeerde gegevens over een bepaalde periode<\/h2>\n<p><b class=\"spoiler_title\">Verzoek<\/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>DB Tijd<\/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>I\/O Tijd<\/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 op total_time<\/h3>\n<p><b class=\"spoiler_title\">Verzoek<\/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 OP TOTALE UITVOERINGSTIJD\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 op totale I\/O tijd<\/h4>\n<p><b class=\"spoiler_title\">Verzoek<\/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 OP BASIS VAN TOTALE I\/O TIJD\n|   #|    queryid|      aanroepen|    aanroepen %|                   I\/O tijd (ms)|db I\/O tijd %\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 op basis van maximale uitvoeringstijd<\/h4>\n<p><b class=\"spoiler_title\">Verzoek<\/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 TUSSEN BEGIN_TIMEPOINT EN EIND_TIMEPOINT\nORDER BY 4 DESC \nLIMIT 10<\/code><\/pre>\n<p><\/p>\n<pre>-----------------------------------------------------------------------------------------\n| TOP10 SQL OP BASIS VAN MAXIMALE UITVOERTIJD\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 op basis van gedeelde buffer lees\/schrijf<\/h4>\n<p><b class=\"spoiler_title\">Verzoek<\/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 TUSSEN BEGIN_TIMEPOINT EN EIND_TIMEPOINT EN\n  ( shared_blks_read &gt; 0 OF shared_blks_written &gt; 0 )\nORDER BY 4 DESC  , 5 DESC \nLIMIT 10<\/code><\/pre>\n<pre>--------------------------------------------------------------------------------------------\n| TOP10 SQL VOOR GEELAATDE BUFFER LEES\/SCHRIJF\n|   #|          snapshot| snapshotID|    queryid|   gedeelde blokken gelezen|  gedeelde blokken geschreven\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>Histogram van de verdeling van queries op maximale uitvoeringstijd<\/h4>\n<p><b class=\"spoiler_title\">Queries<\/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| MAX_TIME HISTOGRAM\n| TOTALE AANTAL OPROEPEN : 33851920\n| MIN TIJD  : 00:00:01.063\n| MAX TIJD  : 00:02:01.869\n---------------------------------------------------------------------------------\n|                      min duur|                      max duur|     oproepen\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 Snapshots per Query per Seconde<\/h4>\n<p><b class=\"spoiler_title\">Queries<\/b><\/p>\n<pre><code class=\"plaintext\">--pg_qps.sql\n--Bereken Query Per Seconde \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 'FOUT - pg_stat_history niet gevonden voor 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 Momentopnamen gesorteerd op QueryPerSeconds aantallen\n-----------------------------------------------------------------------------------------------------------------------------------------------\n|    #|          momentopname| momentopnameID|      oproepen|                      totale dbtijd|        QPS|                          I\/O tijd| I\/O tijd %\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>Urenuitvoeringsgeschiedenis met QueryPerSeconds en I\/O tijd<\/h4>\n<p><b class=\"spoiler_title\">Verzoek<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \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\nORDER BY 2\n<\/code><\/pre>\n<pre>|-----------------------------------------------------------------------------------------------\n| UURVERSCHIL UITVOERINGSGESCHIEDENIS  MET QueryPerSeconds en I\/O-tijd\n-----------------------------------------------------------------------------------------------------------------------------------------------\n| QUERY PER SECONDE GESCHIEDENIS\n|    #|          momentopname| momentopnameID|      oproepen|                      totale dbtijd|        QPS|                          I\/O-tijd| I\/O tijd %\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>Tekst van alle SQL-selecties<\/h4>\n<p><b class=\"spoiler_title\">Verzoek<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  queryid , \n  query \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 , query\n<\/code><\/pre>\n<h2>Conclusie<\/h2>\n<p>\nZoals te zien is, kan met vrij eenvoudige middelen veel nuttige informatie over de belasting en de toestand van de database worden verkregen. <\/p>\n<p><b>Opmerking:<\/b>Als we de queryid in de aanvragen vastleggen, krijgen we de geschiedenis van een afzonderlijke aanvraag (om ruimte te besparen zijn rapporten per afzonderlijke aanvraag weggelaten).<\/p>\n<p>Dus, statistische gegevens over de prestaties van aanvragen zijn beschikbaar en worden verzameld.<br \/>\nDe eerste fase \"gegevensverzameling\" is voltooid.<\/p>\n<p>We kunnen doorgaan naar de tweede fase - \"instelling van prestatiemetingen\".<br \/>\n<img decoding=\"async\" alt=\"Monitoring van de prestaties van PostgreSQL-queries. Deel 1 - rapportage\" src=\"\/wp-content\/uploads\/2019\/04\/a893e49280d4cb425e4667a5c51d2397.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Maar dat is een heel ander verhaal.<\/b><\/p>\n<p><i>Wordt vervolgd\u2026<\/i><br \/>\n<br \/>Bron: <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.3 - 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\/nl\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"nl_NL\" \/>\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\/nl\/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\udd47Prestatiebewaking van PostgreSQL-aanvragen. Deel 1 - rapportage | ProHoster","description":"Ingenieur - afgeleid van het Latijn - betekent ge\u00efnspireerd. Een ingenieur kan alles. (c) R. Diesel. Epigrafen.","canonical_url":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"nl_NL","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\/nl\/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\/nl\/wp-json\/wp\/v2\/posts\/32353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/comments?post=32353"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/32353\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media\/24168"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media?parent=32353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/categories?post=32353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/tags?post=32353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}