{"id":307300,"date":"2020-07-22T09:00:22","date_gmt":"2020-07-22T09:00:22","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=307300"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=307300","title":{"rendered":"\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 PostgreSQL, ClickHouse \u0438 clickhousedb_fdw (PostgreSQL)"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/511992\/\">\n<p>\u0412 \u044d\u0442\u043e\u043c \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0438 \u044f \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 ClickHouse, \u0430 \u043d\u0435 PostgreSQL. \u042f \u0437\u043d\u0430\u044e, \u043a\u0430\u043a\u0438\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 ClickHouse \u044f \u043f\u043e\u043b\u0443\u0447\u0430\u044e. \u0411\u0443\u0434\u0443\u0442 \u043b\u0438 \u044d\u0442\u0438 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b, \u0435\u0441\u043b\u0438 \u044f \u043f\u043e\u043b\u0443\u0447\u0443 \u0434\u043e\u0441\u0442\u0443\u043f \u043a ClickHouse \u0438\u0437 PostgreSQL \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 (FDW)? <\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>\u0418\u0441\u0441\u043b\u0435\u0434\u0443\u0435\u043c\u044b\u043c\u0438 \u0441\u0440\u0435\u0434\u0430\u043c\u0438 \u0431\u0430\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f PostgreSQL v11, clickhousedb_fdw \u0438 \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 ClickHouse. \u0412 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0441\u0447\u0435\u0442\u0435, \u0438\u0437 PostgreSQL v11 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 \u043d\u0430\u0448 clickhousedb_fdw \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 ClickHouse. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c FDW \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u0442\u0435\u043c\u0438 \u0436\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043c\u0438 \u0432 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u043c PostgreSQL \u0438 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u043c ClickHouse.<\/p>\n<p>  <\/p>\n<h3 id=\"baza-dannyh-clickhouse\">\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 Clickhouse<\/h3>\n<p>  <\/p>\n<p>ClickHouse \u2014 \u044d\u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u043b\u043e\u043d\u043e\u043a \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 100-1000 \u0440\u0430\u0437 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u043a \u0431\u0430\u0437\u0430\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043c\u0438\u043b\u043b\u0438\u0430\u0440\u0434\u0430 \u0441\u0442\u0440\u043e\u043a \u043c\u0435\u043d\u0435\u0435 \u0447\u0435\u043c \u0437\u0430 \u0441\u0435\u043a\u0443\u043d\u0434\u0443.<\/p>\n<p>  <\/p>\n<h3 id=\"clickhousedb_fdw\">Clickhousedb_fdw<\/h3>\n<p>  <\/p>\n<p>clickhousedb_fdw \u2014 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0430 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 ClickHouse, \u0438\u043b\u0438 FDW, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u043e\u0442 Percona. \u0412\u043e\u0442 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 GitHub:<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/Percona-Lab\/clickhousedb_fdw\" rel=\"nofollow\">https:\/\/github.com\/Percona-Lab\/clickhousedb_fdw<\/a><\/p>\n<p>  <\/p>\n<p>\u0412 \u043c\u0430\u0440\u0442\u0435 \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0431\u043b\u043e\u0433, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0430\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u043e \u043d\u0430\u0448\u0435\u043c FDW: <a href=\"https:\/\/www.percona.com\/blog\/2019\/03\/29\/postgresql-access-clickhouse-one-of-the-fastest-column-dbmss-with-clickhousedb_fdw\/\" rel=\"nofollow\">https:\/\/www.percona.com\/blog\/2019\/03\/29\/postgresql-access-clickhouse-one-of-the-fastest-column-dbmss-with-clickhousedb_fdw\/<\/a><\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u044d\u0442\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 FDW \u0434\u043b\u044f ClickHouse, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 SELECT from, \u0438 INSERT INTO, \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 ClickHouse \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 PostgreSQL v11.<\/p>\n<p>  <\/p>\n<p>FDW \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a aggregate \u0438 join. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0432\u044b\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0437\u0430 \u0441\u0447\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0435\u043c\u043a\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439.<\/p>\n<p>  <\/p>\n<h3 id=\"benchmark-environment\">Benchmark environment<\/h3>\n<p>  <\/p>\n<ul>\n<li>Supermicro server:<br \/> \n<ul>\n<li>Intel&reg; Xeon&reg; CPU E5-2683 v3 @ 2.00GHz<\/li>\n<li>2 sockets \/ 28 cores \/ 56 threads<\/li>\n<li>Memory: 256GB of RAM<\/li>\n<li>Storage: Samsung SM863 1.9TB Enterprise SSD<\/li>\n<li>Filesystem: ext4\/xfs<\/li>\n<\/ul>\n<\/li>\n<li>OS: Linux smblade01 4.15.0-42-generic #45~16.04.1-Ubuntu<\/li>\n<li>PostgreSQL: version 11<\/li>\n<\/ul>\n<p>  <\/p>\n<h3 id=\"benchmark-tests\">Benchmark tests<\/h3>\n<p>  <\/p>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0448\u0438\u043d\u043e\u0439, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u00ab\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u043c\u0430\u044f \u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430\u00bb \u0441 1987 \u043f\u043e 2018 \u0433\u043e\u0434. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0434\u0430\u043d\u043d\u044b\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0433\u043e \u0437\u0434\u0435\u0441\u044c:<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/Percona-Lab\/ontime-airline-performance\/blob\/master\/download.sh\" rel=\"nofollow\">https:\/\/github.com\/Percona-Lab\/ontime-airline-performance\/blob\/master\/download.sh<\/a><\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0437\u043c\u0435\u0440 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 85 \u0413\u0411, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044f \u043e\u0434\u043d\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438\u0437 109 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432.<\/p>\n<p>  <\/p>\n<h4 id=\"benchmark-queries\">Benchmark Queries<\/h4>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f ClickHouse, clickhousedb_fdw \u0438 PostgreSQL.<\/p>\n<p>  <\/p>\n<div class=\"scrollable-table\">\n<table>\n<thead>\n<tr>\n<th><strong>Q#<\/strong><\/th>\n<th><strong>Query Contains Aggregates and Group By<\/strong><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Q1<\/td>\n<td>SELECT DayOfWeek, count(*) AS c FROM ontime WHERE Year &gt;= 2000 AND Year &lt;= 2008 GROUP BY DayOfWeek ORDER BY c DESC;<\/td>\n<\/tr>\n<tr>\n<td>Q2<\/td>\n<td>SELECT DayOfWeek, count(*) AS c FROM ontime WHERE DepDelay&gt;10 AND Year &gt;= 2000 AND Year &lt;= 2008 GROUP BY DayOfWeek ORDER BY c DESC;<\/td>\n<\/tr>\n<tr>\n<td>Q3<\/td>\n<td>SELECT Origin, count(*) AS c FROM ontime WHERE DepDelay&gt;10 AND Year &gt;= 2000 AND Year &lt;= 2008 GROUP BY Origin ORDER BY c DESC LIMIT 10;<\/td>\n<\/tr>\n<tr>\n<td>Q4<\/td>\n<td>SELECT Carrier, count(<em>) FROM ontime WHERE DepDelay&gt;10 AND Year = 2007 GROUP BY Carrier ORDER BY count(<\/em>) DESC;<\/td>\n<\/tr>\n<tr>\n<td>Q5<\/td>\n<td>SELECT a.Carrier, c, c2, c<em>1000\/c2 as c3 FROM ( SELECT Carrier, count(<\/em>) AS c FROM ontime WHERE DepDelay&gt;10 AND Year=2007 GROUP BY Carrier ) a INNER JOIN ( SELECT Carrier,count(*) AS c2 FROM ontime WHERE Year=2007 GROUP BY Carrier)b on a.Carrier=b.Carrier ORDER BY c3 DESC;<\/td>\n<\/tr>\n<tr>\n<td>Q6<\/td>\n<td>SELECT a.Carrier, c, c2, c<em>1000\/c2 as c3 FROM ( SELECT Carrier, count(<\/em>) AS c FROM ontime WHERE DepDelay&gt;10 AND Year &gt;= 2000 AND Year &lt;= 2008 GROUP BY Carrier) a INNER JOIN ( SELECT Carrier, count(*) AS c2 FROM ontime WHERE Year &gt;= 2000 AND Year &lt;= 2008 GROUP BY Carrier ) b on a.Carrier=b.Carrier ORDER BY c3 DESC;<\/td>\n<\/tr>\n<tr>\n<td>Q7<\/td>\n<td>SELECT Carrier, avg(DepDelay) * 1000 AS c3 FROM ontime WHERE Year &gt;= 2000 AND Year &lt;= 2008 GROUP BY Carrier;<\/td>\n<\/tr>\n<tr>\n<td>Q8<\/td>\n<td>SELECT Year, avg(DepDelay) FROM ontime GROUP BY Year;<\/td>\n<\/tr>\n<tr>\n<td>Q9<\/td>\n<td>select Year, count(*) as c1 from ontime group by Year;<\/td>\n<\/tr>\n<tr>\n<td>Q10<\/td>\n<td>SELECT avg(cnt) FROM (SELECT Year,Month,count(*) AS cnt FROM ontime WHERE DepDel15=1 GROUP BY Year,Month) a;<\/td>\n<\/tr>\n<tr>\n<td>Q11<\/td>\n<td>select avg(c1) from (select Year,Month,count(*) as c1 from ontime group by Year,Month) a;<\/td>\n<\/tr>\n<tr>\n<td>Q12<\/td>\n<td>SELECT OriginCityName, DestCityName, count(*) AS c FROM ontime GROUP BY OriginCityName, DestCityName ORDER BY c DESC LIMIT 10;<\/td>\n<\/tr>\n<tr>\n<td>Q13<\/td>\n<td>SELECT OriginCityName, count(*) AS c FROM ontime GROUP BY OriginCityName ORDER BY c DESC LIMIT 10;<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><strong>Query Contains Joins<\/strong><\/td>\n<\/tr>\n<tr>\n<td>Q14<\/td>\n<td>SELECT a.Year, c1\/c2 FROM ( select Year, count(<em>)<\/em>1000 as c1 from ontime WHERE DepDelay&gt;10 GROUP BY Year) a INNER JOIN (select Year, count(*) as c2 from ontime GROUP BY Year ) b on a.Year=b.Year ORDER BY a.Year;<\/td>\n<\/tr>\n<tr>\n<td>Q15<\/td>\n<td>SELECT a.\u201dYear\u201d, c1\/c2 FROM ( select \u201cYear\u201d, count(<em>)<\/em>1000 as c1 FROM fontime WHERE \u201cDepDelay\u201d&gt;10 GROUP BY \u201cYear\u201d) a INNER JOIN (select \u201cYear\u201d, count(*) as c2 FROM fontime GROUP BY \u201cYear\u201d ) b on a.\u201dYear\u201d=b.\u201dYear\u201d;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>  <\/p>\n<p><em>Table-1: Queries used in benchmark<\/em><\/p>\n<p>  <\/p>\n<h4 id=\"query-executions\">Query executions<\/h4>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445: PostgreSQL \u0441 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u043c\u0438 \u0438 \u0431\u0435\u0437 \u043d\u0438\u0445, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 ClickHouse \u0438 clickhousedb_fdw. \u0412\u0440\u0435\u043c\u044f \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445.<\/p>\n<p>  <\/p>\n<div class=\"scrollable-table\">\n<table>\n<thead>\n<tr>\n<th><strong>Q#<\/strong><\/th>\n<th><strong>PostgreSQL<\/strong><\/th>\n<th><strong>PostgreSQL (Indexed)<\/strong><\/th>\n<th><strong>ClickHouse<\/strong><\/th>\n<th><strong>clickhousedb_fdw<\/strong><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Q1<\/td>\n<td>27920<\/td>\n<td>19634<\/td>\n<td>23<\/td>\n<td>57<\/td>\n<\/tr>\n<tr>\n<td>Q2<\/td>\n<td>35124<\/td>\n<td>17301<\/td>\n<td>50<\/td>\n<td>80<\/td>\n<\/tr>\n<tr>\n<td>Q3<\/td>\n<td>34046<\/td>\n<td>15618<\/td>\n<td>67<\/td>\n<td>115<\/td>\n<\/tr>\n<tr>\n<td>Q4<\/td>\n<td>31632<\/td>\n<td>7667<\/td>\n<td>25<\/td>\n<td>37<\/td>\n<\/tr>\n<tr>\n<td>Q5<\/td>\n<td>47220<\/td>\n<td>8976<\/td>\n<td>27<\/td>\n<td>60<\/td>\n<\/tr>\n<tr>\n<td>Q6<\/td>\n<td>58233<\/td>\n<td>24368<\/td>\n<td>55<\/td>\n<td>153<\/td>\n<\/tr>\n<tr>\n<td>Q7<\/td>\n<td>30566<\/td>\n<td>13256<\/td>\n<td>52<\/td>\n<td>91<\/td>\n<\/tr>\n<tr>\n<td>Q8<\/td>\n<td>38309<\/td>\n<td>60511<\/td>\n<td>112<\/td>\n<td>179<\/td>\n<\/tr>\n<tr>\n<td>Q9<\/td>\n<td>20674<\/td>\n<td>37979<\/td>\n<td>31<\/td>\n<td>81<\/td>\n<\/tr>\n<tr>\n<td>Q10<\/td>\n<td>34990<\/td>\n<td>20102<\/td>\n<td>56<\/td>\n<td>148<\/td>\n<\/tr>\n<tr>\n<td>Q11<\/td>\n<td>30489<\/td>\n<td>51658<\/td>\n<td>37<\/td>\n<td>155<\/td>\n<\/tr>\n<tr>\n<td>Q12<\/td>\n<td>39357<\/td>\n<td>33742<\/td>\n<td>186<\/td>\n<td>1333<\/td>\n<\/tr>\n<tr>\n<td>Q13<\/td>\n<td>29912<\/td>\n<td>30709<\/td>\n<td>101<\/td>\n<td>384<\/td>\n<\/tr>\n<tr>\n<td>Q14<\/td>\n<td>54126<\/td>\n<td>39913<\/td>\n<td>124<\/td>\n<td>1364212<\/td>\n<\/tr>\n<tr>\n<td>Q15<\/td>\n<td>97258<\/td>\n<td>30211<\/td>\n<td>245<\/td>\n<td>259<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>  <\/p>\n<p><em>Table-1: Time taken to execute the queries used in benchmark<\/em><\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432<\/p>\n<p>  <\/p>\n<p>\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445, \u043e\u0441\u044c X \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u043e\u043c\u0435\u0440 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446 \u0432\u044b\u0448\u0435, \u0430 \u043e\u0441\u044c Y \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b ClickHouse \u0438 \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 postgres \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e clickhousedb_fdw, \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u044b. \u0418\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0433\u0440\u043e\u043c\u043d\u0430\u044f \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u043c\u0435\u0436\u0434\u0443 PostgreSQL \u0438 ClickHouse, \u043d\u043e \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u043c\u0435\u0436\u0434\u0443 ClickHouse \u0438 clickhousedb_fdw.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/4p\/go\/3q\/4pgo3q4mxl5izqbkri-tfugqew4.png\"><\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0442 \u0433\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043c\u0435\u0436\u0434\u0443 ClickhouseDB \u0438 clickhousedb_fdw. \u0412 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u044b FDW \u043d\u0435 \u0442\u0430\u043a \u0432\u0435\u043b\u0438\u043a\u0438 \u0438 \u0435\u0434\u0432\u0430 \u043b\u0438 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b, \u043a\u0440\u043e\u043c\u0435 Q12. \u042d\u0442\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 ORDER BY. \u0418\u0437-\u0437\u0430 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f ORDER BY GROUP\/BY \u0438 ORDER BY \u043d\u0435 \u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0434\u043e ClickHouse.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 2 \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0441\u043a\u0430\u0447\u043e\u043a \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445 Q12 \u0438 Q13. \u041f\u043e\u0432\u0442\u043e\u0440\u044e\u0441\u044c, \u044d\u0442\u043e \u0432\u044b\u0437\u0432\u0430\u043d\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c ORDER BY. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u044d\u0442\u043e, \u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b \u0437\u0430\u043f\u0440\u043e\u0441\u044b Q-14 \u0438 Q-15 \u0441 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c ORDER BY \u0438 \u0431\u0435\u0437 \u043d\u0435\u0433\u043e. \u0411\u0435\u0437 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f ORDER BY \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 259 \u043c\u0441, \u0430 \u0441 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c ORDER BY \u2014 1364212. \u0414\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u044f \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u044e \u043e\u0431\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0430 \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>Q15: Without ORDER BY Clause<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">bm=# EXPLAIN VERBOSE SELECT a.&quot;Year&quot;, c1\/c2       FROM (SELECT &quot;Year&quot;, count(*)*1000 AS c1 FROM fontime WHERE &quot;DepDelay&quot; &gt; 10 GROUP BY &quot;Year&quot;) a      INNER JOIN(SELECT &quot;Year&quot;, count(*) AS c2 FROM fontime GROUP BY &quot;Year&quot;) b ON a.&quot;Year&quot;=b.&quot;Year&quot;;<\/code><\/pre>\n<p>  <\/p>\n<p>Q15: Query Without ORDER BY Clause<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">QUERY PLAN                                                       Hash Join  (cost=2250.00..128516.06 rows=50000000 width=12)   Output: fontime.&quot;Year&quot;, (((count(*) * 1000)) \/ b.c2)   Inner Unique: true   Hash Cond: (fontime.&quot;Year&quot; = b.&quot;Year&quot;)   -&gt;  Foreign Scan  (cost=1.00..-1.00 rows=100000 width=12)         Output: fontime.&quot;Year&quot;, ((count(*) * 1000))         Relations: Aggregate on (fontime)         Remote SQL: SELECT &quot;Year&quot;, (count(*) * 1000) FROM &quot;default&quot;.ontime WHERE ((&quot;DepDelay&quot; &gt; 10)) GROUP BY &quot;Year&quot;   -&gt;  Hash  (cost=999.00..999.00 rows=100000 width=12)         Output: b.c2, b.&quot;Year&quot;         -&gt;  Subquery Scan on b  (cost=1.00..999.00 rows=100000 width=12)               Output: b.c2, b.&quot;Year&quot;               -&gt;  Foreign Scan  (cost=1.00..-1.00 rows=100000 width=12)                     Output: fontime_1.&quot;Year&quot;, (count(*))                     Relations: Aggregate on (fontime)                     Remote SQL: SELECT &quot;Year&quot;, count(*) FROM &quot;default&quot;.ontime GROUP BY &quot;Year&quot;(16 rows)<\/code><\/pre>\n<p>  <\/p>\n<p>Q14: Query With ORDER BY Clause<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">bm=# EXPLAIN VERBOSE SELECT a.&quot;Year&quot;, c1\/c2 FROM(SELECT &quot;Year&quot;, count(*)*1000 AS c1 FROM fontime WHERE &quot;DepDelay&quot; &gt; 10 GROUP BY &quot;Year&quot;) a       INNER JOIN(SELECT &quot;Year&quot;, count(*) as c2 FROM fontime GROUP BY &quot;Year&quot;) b  ON a.&quot;Year&quot;= b.&quot;Year&quot;       ORDER BY a.&quot;Year&quot;;<\/code><\/pre>\n<p>  <\/p>\n<p>Q14: Query Plan with ORDER BY Clause<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">QUERY PLAN  Merge Join\u00a0 (cost=2.00..628498.02 rows=50000000 width=12)\u00a0\u00a0  Output: fontime.&quot;Year&quot;, (((count(*) * 1000)) \/ (count(*)))\u00a0\u00a0  Inner Unique: true\u00a0\u00a0 Merge Cond: (fontime.&quot;Year&quot; = fontime_1.&quot;Year&quot;)\u00a0\u00a0  -&gt;\u00a0 GroupAggregate\u00a0 (cost=1.00..499.01 rows=1 width=12)\u00a0 \u00a0 \u00a0 \u00a0  Output: fontime.&quot;Year&quot;, (count(*) * 1000)\u00a0\u00a0 \u00a0 \u00a0 \u00a0  Group Key: fontime.&quot;Year&quot;\u00a0\u00a0 \u00a0 \u00a0 \u00a0  -&gt;\u00a0 Foreign Scan on public.fontime\u00a0 (cost=1.00..-1.00 rows=100000 width=4)\u00a0\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0  Remote SQL: SELECT &quot;Year&quot; FROM &quot;default&quot;.ontime WHERE ((&quot;DepDelay&quot; &gt; 10))              ORDER BY &quot;Year&quot; ASC\u00a0\u00a0  -&gt;\u00a0 GroupAggregate\u00a0 (cost=1.00..499.01 rows=1 width=12)\u00a0\u00a0 \u00a0 \u00a0 \u00a0  Output: fontime_1.&quot;Year&quot;, count(*)\u00a0\u00a0 \u00a0 \u00a0 \u00a0 Group Key: fontime_1.&quot;Year&quot;\u00a0\u00a0 \u00a0 \u00a0 \u00a0  -&gt;\u00a0 Foreign Scan on public.fontime fontime_1\u00a0 (cost=1.00..-1.00 rows=100000 width=4)\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0  Remote SQL: SELECT &quot;Year&quot; FROM &quot;default&quot;.ontime ORDER BY &quot;Year&quot; ASC(16 rows)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u044b\u0432\u043e\u0434<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u044d\u0442\u0438\u0445 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442, \u0447\u0442\u043e ClickHouse \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u0443\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0430 clickhousedb_fdw \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 ClickHouse \u0438\u0437 PostgreSQL. \u0425\u043e\u0442\u044f \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 clickhousedb_fdw \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u044b, \u043e\u043d\u0438 \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b \u0438 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043c\u044b \u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e, \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u043e\u0439 \u043f\u0440\u0438 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 ClickHouse. \u042d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442, \u0447\u0442\u043e fdw \u0432 PostgreSQL \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0447\u0430\u0442 \u043f\u043e Clickhouse <a href=\"https:\/\/t.me\/clickhouse_ru\" rel=\"nofollow\">https:\/\/t.me\/clickhouse_ru<\/a><br \/>  \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0447\u0430\u0442 \u043f\u043e PostgreSQL <a href=\"https:\/\/t.me\/pgsql\" rel=\"nofollow\">https:\/\/t.me\/pgsql<\/a><\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/511992\/\"> https:\/\/habr.com\/ru\/post\/511992\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/511992\/\">\n<p>\u0412 \u044d\u0442\u043e\u043c \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0438 \u044f \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 ClickHouse, \u0430 \u043d\u0435 PostgreSQL. \u042f \u0437\u043d\u0430\u044e, \u043a\u0430\u043a\u0438\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 ClickHouse \u044f \u043f\u043e\u043b\u0443\u0447\u0430\u044e. \u0411\u0443\u0434\u0443\u0442 \u043b\u0438 \u044d\u0442\u0438 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b, \u0435\u0441\u043b\u0438 \u044f \u043f\u043e\u043b\u0443\u0447\u0443 \u0434\u043e\u0441\u0442\u0443\u043f \u043a ClickHouse \u0438\u0437 PostgreSQL \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 (FDW)? <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-307300","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/307300","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=307300"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/307300\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=307300"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=307300"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=307300"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}