{"id":1497,"date":"2018-01-19T19:22:54","date_gmt":"2018-01-19T19:22:54","guid":{"rendered":"http:\/\/goofy-trucks.flywheelsites.com\/mysql-and-postgresql-compared-page-2\/"},"modified":"2018-01-19T19:24:50","modified_gmt":"2018-01-19T19:24:50","slug":"mysql-and-postgresql-compared-page-2","status":"publish","type":"post","link":"https:\/\/phpbuilder.com\/mysql-and-postgresql-compared-page-2\/","title":{"rendered":"MySQL and PostgreSQL Compared Page 2"},"content":{"rendered":"<div class=\"phpbuilder-content\">\n<div class=\"phpbuilder-meta\">\n<div class=\"\">By Tim Perdue<\/div>\n<div class=\"\">on July 30, 2000<\/div>\n<\/p><\/div>\n<div id=\"overflow-content\">\n<h2>Methodology<\/h2>\n<div class=\"articlePara\">\nTo try to make this as realistic as possible, I took an actual page from a<br \/>\nwebsite and made it portable across both MySQL and Postgres. This basically<br \/>\nmeant replacing all mysql_query() calls with pg_exec(). This page involves<br \/>\na lot of selects and joins, as probably most pages on a typical website do.<\/div>\n<div class=\"articlePara\">\nOnce the test page was up and debugged, I then ran &#8220;ab&#8221;, the &#8220;Apache Benchmarking&#8221;<br \/>\nutility, from my workstation across my 100-mbit LAN to the quad-xeon machine. To<br \/>\nget an idea of scalability under load, I varied the &#8220;concurrent connections&#8221;<br \/>\non ab from 10-120, while leaving the number of page views steady at 1000.<\/div>\n<div class=\"articlePara\">\nTo more closely simulate real-world use, I set up a random-number generator in<br \/>\nthe script that inserts a row into the database on 10% of the page views. My<br \/>\nown numbers on PHPBuilder show that about 10% of all pages in the discussion<br \/>\nforums are for posting new messages.<\/div>\n<div class=\"articlePara\">\nFurther, as mentioned above, I used real data from a production database. You<br \/>\ncan&#8217;t get a whole lot more realistic than this scenario.<\/div>\n<h2>The Numbers<\/h2>\n<div class=\"articlePara\">\n<a href=\"tim20000705-res.html\" target=\"_blank\">[Raw Test Results]<\/a><\/div>\n<div class=\"articlePara\">\nThe most interesting thing about my test results was to see how much of a load<br \/>\nPostgres could withstand before giving any errors. In fact, Postgres seemed to<br \/>\nscale 3 times higher than MySQL before giving any errors at all. MySQL<br \/>\nbegins collapsing at about 40-50 concurrent connections, whereas Postgres<br \/>\nhandily scaled to 120 before balking. My guess is, that Postgres could have gone<br \/>\nfar past 120 connections with enough memory and CPU.<\/div>\n<div class=\"articlePara\">\nOn the surface, this can appear to be a huge win for Postgres, but if you<br \/>\nlook at the results in more detail, you&#8217;ll see that Postgres took up to 2-3<br \/>\ntimes longer to generate each page, so it needs to scale 2-3 times higher<br \/>\njust to break even with MySQL. So in terms of max numbers of pages generated<br \/>\nconcurrently without giving errors, it&#8217;s pretty much a dead heat between<br \/>\nthe two databases. In terms of generating one page at a time, MySQL does it<br \/>\nup to 2-3 times faster.<\/div>\n<div class=\"articlePara\">\nAnother interesting point was that MySQL crumbles faster in the &#8220;10%<br \/>\ninsert&#8221; test described above. Research reveals that MySQL locks the entire<br \/>\ntable when an insert occurs, while Postgres has a pretty nifty &#8220;better than<br \/>\nrow-level locking&#8221; feature. This difference quickly causes MySQL to pile up concurrent<br \/>\nconnections and thus collapse. The same is true if you are doing a large select<br \/>\nout of a database while another process is inserting into that table. Postgres<br \/>\nis completely unfazed, while MySQL piles up connections until it falls apart<br \/>\nlike a house of cards.<\/div>\n<div class=\"articlePara\">\nFor those of you wondering about persistent connections in PHP, they don&#8217;t<br \/>\nappear to benefit MySQL that much, whereas they are a clear boon for Postgres.<br \/>\nIn fact, Postgres benchmarked as much as 30% faster just by using persistent<br \/>\nconnections. That tells me that Postgres has a tremendous amount of overhead in<br \/>\nits connection-opening and authentication process. Some of this may be the<br \/>\nfault of Linux and its relatively lame process scheduler. Still, MySQL on the<br \/>\nsame box beat it handily no matter how you look at it.<\/div>\n<\/div>\n<p><\/p>\n<div style=\"float: left; padding:15px; color:#17AAF3\">\n<div style=\"float:left; padding:2px;\"><a class=\"paginationPageLink\" href=\"tim20000705.html\">\u00ab Previous Page<\/a><\/div>\n<div style=\"float:left; padding:2px 4px 2px 4px;\"><a class=\"pageNumber\" href=\"tim20000705.html\">1<\/a> <\/div>\n<div style=\"float:left; font-size:16px; color:#FF7A22; padding:2px 2px 2px 2px; \">| <\/div>\n<div style=\"background-color:#B6E5FC; font-size:16px; margin-top:1px; padding:1px 4px 1px 4px; color:#000; font-style:bold; float:left;\">2<\/div>\n<div style=\"float:left; font-size:16px; color:#FF7A22; padding:2px 2px 2px 2px; \">| <\/div>\n<div style=\"float:left; padding:2px 4px 2px 4px;\"><a class=\"pageNumber\" href=\"tim200007059ba9.html?page=3\">3<\/a> <\/div>\n<div style=\"float:left; font-size:16px; color:#FF7A22; padding:2px 2px 2px 2px; \">| <\/div>\n<div style=\"float:left; padding:2px 4px 2px 4px;\"><a class=\"pageNumber\" href=\"tim20000705fdb0.html?page=4\">4<\/a> <\/div>\n<div style=\"float:left; font-size:16px; color:#FF7A22; padding:2px 2px 2px 2px; \">| <\/div>\n<div style=\"float:left; padding:2px 4px 2px 4px;\"><a class=\"pageNumber\" href=\"tim20000705af4d.html?page=5\">5<\/a> <\/div>\n<div style=\"float:left; padding:2px;\"><a class=\"paginationPageLink\" href=\"tim200007059ba9.html?page=3\">Next Page \u00bb<\/a><\/div>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>By Tim Perdue on July 30, 2000 Methodology To try to make this as realistic as possible, I took an actual page from a website and made it portable across both MySQL and Postgres. This basically meant replacing all mysql_query() calls with pg_exec(). This page involves a lot of selects&#8230; <a href=\"https:\/\/phpbuilder.com\/mysql-and-postgresql-compared-page-2\/\" class=\"readmore\"><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-1497","post","type-post","status-publish","format-standard","hentry","category-tutorials"],"_links":{"self":[{"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/posts\/1497","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/comments?post=1497"}],"version-history":[{"count":1,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/posts\/1497\/revisions"}],"predecessor-version":[{"id":3341,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/posts\/1497\/revisions\/3341"}],"wp:attachment":[{"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/media?parent=1497"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/categories?post=1497"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/tags?post=1497"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}