{"id":1941,"date":"2013-11-01T12:27:44","date_gmt":"2013-11-01T12:27:44","guid":{"rendered":"http:\/\/bicortex.com\/?p=1941"},"modified":"2018-07-23T08:21:06","modified_gmt":"2018-07-23T08:21:06","slug":"amazon-redshift-review-data-warehouse-in-the-cloud-is-here-part-2","status":"publish","type":"post","link":"http:\/\/bicortex.com\/bicortex\/amazon-redshift-review-data-warehouse-in-the-cloud-is-here-part-2\/","title":{"rendered":"Amazon Redshift Review &#8211; Data Warehouse in the Cloud Is Here, Part 2"},"content":{"rendered":"<h3 style=\"text-align: center;\">Background And Environment Specs Recap<\/h3>\n<p style=\"text-align: justify;\">In the <a href=\"http:\/\/bicortex.com\/amazon-redshift-review-data-warehouse-in-the-cloud-is-here-part-1\/\" target=\"_blank\"><b>FIRST<\/b><\/a> part of this series I briefly explored the background of Amazon\u2019s Redshift data warehouse offering as well as outlined the environments and tools used for managing test datasets. I also recreated TICKIT database schema on all instances provisioned for testing and preloaded them with dummy data. In this post I would like to explore the performance findings from running a bunch of sample SQL queries to find out how they behave under load. Final post outlining how to connect and use data stored in Redshift can be found <a href=\"http:\/\/bicortex.com\/amazon-redshift-review-data-warehouse-in-the-cloud-is-here-part-3\/\" target=\"_blank\"><b>HERE<\/b><\/a>.<\/p>\n<p style=\"text-align: justify;\">As mentioned in my <a href=\"http:\/\/bicortex.com\/amazon-redshift-review-data-warehouse-in-the-cloud-is-here-part-1\/\" target=\"_blank\"><b>FIRST<\/b><\/a> post, all datasets which populated TICKIT sample database were quite small so I needed to synthetically expand one of the tables in order to increase data volumes to make the whole exercise viable. Using nothing but SQL I \u2018stretched out\u2019 my Sales fact table to around 50,000,000 records which is hardly enough for any database to break a sweat, but given the free storage limit on Amazon S3 is only 5 GB (you can also use DynamoDB as a file storage) and that my home internet bandwidth is still stuck on ADSL2 I had to get a little creative with the SQL queries rather than try to push for higher data volumes. Testing methodology was quite simple here \u2013 using mocked-up SQL SELECT statements, for each query executed I recorded execution time on all environments and plucked them into a graph for comparison. None of those statements represent any business function so I did not focus on any specific output or result; the idea was to simply make them run and wait until completion, taking note of how long it took from beginning to end. Each time the query was executed, the instance got restarted to ensure cold cache and full system resources available to database engine. I also tried to make my SQL as generic as possible. By default, SQL is not a very verbose language, with a not a lot of dichotomies between different vendors. Most of the core syntax principles apply to both PG\/SQL and Microsoft T-SQL alike. However, there are some small distinctions which can get \u2018lost in translation\u2019 therefore I tried to keep the queries are as generic and universal as possible.<\/p>\n<p style=\"text-align: justify;\">As far as physical infrastructure composition, the image below contains a quick recap of the testing environment used for this evaluation. Initially, I planned to test my queries on 3 different Redshift deployments \u2013 a single and a multi-node Redshift XL instance as well as a single Redshift 8XL instance, however, after casually running a few queries and seeing the performance level Redshift is capable of I decided to scale back and run only with Redshift XL class in a single and multi-node configurations.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Test_Env_Specs_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1926\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Test_Env_Specs_ART.png\" alt=\"Test_Env_Specs_ART\" width=\"580\" height=\"325\" \/><\/a>Graphing the results, for simplicity sake, I assigned the following monikers to each environment:<\/p>\n<ul>\n<li>&#8216;Local Instance&#8217; &#8211; my local SQL Server 2012 deployment<\/li>\n<li>&#8216;RDS\u00a0SQL Server&#8217; &#8211; High-Memory Quadruple Extra Large DB Instance of SQL Server 2012<\/li>\n<li>&#8216;1 x Redshift XL&#8217; \u2013 Single High Storage Extra Large (XL) Redshift DW node (1 x dw.hs1.xlarge)<\/li>\n<li>&#8216;4 x Redshift XL&#8217; \u2013 Four High Storage Extra Large (XL) Redshift DW nodes (4 x dw.hs1.xlarge)<\/li>\n<\/ul>\n<h3 style=\"text-align: center;\">Test Results<\/h3>\n<p style=\"text-align: justify;\">All SQL queries run to collect execution times (expressed in seconds) as well as graphical representation of their duration are as per below.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n--QUERY 1\r\nSELECT COUNT(*) FROM\r\n\t(SELECT COUNT(*) AS counts, salesid, listid, sellerid, buyerid,\r\n\teventid, dateid, qtysold, pricepaid, commission, saletime\r\n\tFROM sales\r\n\tGROUP BY salesid, listid, sellerid, buyerid, eventid,\r\n\tdateid, qtysold, pricepaid, commission, saletime) sub\r\n<\/pre>\n<p><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query1_Results_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1944\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query1_Results_ART.png\" alt=\"Query1_Results_ART\" width=\"580\" height=\"280\" srcset=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query1_Results_ART.png 580w, http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query1_Results_ART-300x144.png 300w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n--QUERY 2\r\nWITH cte AS (\r\n\tSELECT\r\n\t\tSUM(s.pricepaid) AS pricepaid,\r\n\t\tsub.*,\r\n\t\tu1.email,\r\n\t\tDENSE_RANK() OVER (PARTITION BY sub.totalprice ORDER BY d.caldate DESC) AS daterank\r\n\tFROM sales s  JOIN\r\n\t\t(SELECT l.totalprice, l.listid, v.venuecity, c.catdesc\r\n\t\tFROM listing l\r\n\t\tLEFT JOIN event e on l.eventid = e.eventid\r\n\t\tINNER JOIN category c on e.catid = c.catid\r\n\t\tINNER JOIN venue v on e.venueid = v.venueid\r\n\t\tGROUP BY v.venuecity, c.catdesc, l.listid, l.totalprice) sub\r\n\tON s.listid = sub.listid\r\n\tLEFT JOIN users u1 on s.buyerid = u1.userid\r\n\tLEFT JOIN Date d on d.dateid = s.dateid\r\n\tGROUP BY sub.totalprice, sub.listid, sub.venuecity, sub.catdesc, u1.email, d.caldate)\r\nSELECT COUNT(*) FROM cte\r\n<\/pre>\n<p><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query2_Results_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1945\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query2_Results_ART.png\" alt=\"Query2_Results_ART\" width=\"580\" height=\"280\" srcset=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query2_Results_ART.png 580w, http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query2_Results_ART-300x144.png 300w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n--QUERY 3\r\nSELECT COUNT(*) FROM(\r\nSELECT s.*, u.* FROM sales s\r\n\t\tLEFT JOIN event e on s.eventid = e.eventid\r\n\t\tLEFT JOIN date d on d.dateid = s.dateid\r\n\t\tLEFT JOIN users u on u.userid = s.buyerid\r\n\t\tLEFT JOIN listing l on l.listid = s.listid\r\n\t\tLEFT JOIN category c on c.catid = e.catid\r\n\t\tLEFT JOIN venue v on v.venueid = e.venueid\r\n\tINTERSECT\r\nSELECT s.*, u.* FROM sales s\r\n\t\tLEFT JOIN event e on s.eventid = e.eventid\r\n\t\tLEFT JOIN date d on d.dateid = s.dateid\r\n\t\tLEFT JOIN users u on u.userid = s.buyerid\r\n\t\tLEFT JOIN listing l on l.listid = s.listid\r\n\t\tLEFT JOIN category c on c.catid = e.catid\r\n\t\tLEFT JOIN venue v on v.venueid = e.venueid\r\n\t\tWHERE d.holiday =0) sub\r\n<\/pre>\n<p><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query3_Results_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1946\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query3_Results_ART.png\" alt=\"Query3_Results_ART\" width=\"580\" height=\"280\" srcset=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query3_Results_ART.png 580w, http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query3_Results_ART-300x144.png 300w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n--QUERY 4\r\nWITH Temp (eventname, starttime, eventid) AS\r\n\t(SELECT ev.eventname, ev.starttime, ev.eventid\r\n\tFROM Event ev\r\n\tWHERE\tNOT EXISTS\t\r\n\t\t\t(SELECT 1 FROM Sales s\r\n\t\t\tWHERE s.pricepaid  &gt; 500 AND s.pricepaid &lt; 900 AND s.eventid = ev.eventid) \t\r\n\t\t\tAND  EXISTS\t(SELECT 1 FROM Sales s \r\n\t\t\tWHERE s.qtysold  &gt;= 4 AND s.eventid = ev.eventid))\r\nSELECT COUNT(t.eventid) AS EvCount,\r\nSUM(l.totalprice)  - SUM((CAST(l.numtickets AS Decimal(8,2)) * l.priceperticket * 0.9)) as TaxPaid\r\nFROM Temp t JOIN Listing l ON l.eventid = t.eventid\r\nWHERE t.starttime &lt;= l.listtime\r\n<\/pre>\n<p><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query4_Results_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1947\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query4_Results_ART.png\" alt=\"Query4_Results_ART\" width=\"580\" height=\"280\" srcset=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query4_Results_ART.png 580w, http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query4_Results_ART-300x144.png 300w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n--QUERY 5\r\nSELECT COUNT(*) FROM\r\n\t(SELECT\r\n\t\tSUM(sub1.pricepaid) AS price_paid,\r\n\t\tsub1.caldate AS date,\r\n\t\tsub1.username\r\n\tFROM\r\n\t\t(select  s.pricepaid, d.caldate, u.username\r\n\t\tFROM Sales s\r\n\t\tLEFT JOIN date d on s.dateid=s.dateid\r\n\t\tLEFT JOIN users u on s.buyerid = u.userid\r\n\t\tWHERE s.saletime BETWEEN '2008-12-01' AND '2008-12-31'\r\n\t\t) sub1\r\n\tGROUP BY sub1.caldate, sub1.username\r\n\t) as sub2\r\n<\/pre>\n<p><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query5_Results_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1948\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query5_Results_ART.png\" alt=\"Query5_Results_ART\" width=\"580\" height=\"280\" srcset=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query5_Results_ART.png 580w, http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query5_Results_ART-300x144.png 300w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n--QUERY 6\r\nWITH CTE1 (c1) AS\r\n\t\t(SELECT COUNT(1) as c1 FROM Sales s\r\n\t\tWHERE saletime BETWEEN '2008-12-01' AND '2008-12-31' \r\n\t\tGROUP BY salesid \r\n\t\tHAVING COUNT(*)=1),\r\n\tCTE2 (c2) AS\r\n\t\t(SELECT COUNT(1) as c2 FROM Listing e\r\n\t\tWHERE listtime BETWEEN '2008-12-01' AND '2008-12-31' \r\n\t\tGROUP BY listid\t\r\n\t\tHAVING COUNT(*)=1),\r\n\tCTE3 (c3) AS\r\n\t\t(SELECT COUNT(1) as c3 FROM Date d\t\r\n\t\tGROUP BY dateid \r\n\t\tHAVING COUNT(*)=1)\r\nSELECT COUNT(*) FROM Cte1\r\n\t\t\t\t\tRIGHT JOIN CTE2 ON CTE1.c1 &lt;&gt; CTE2.c2\r\n\t\t\t\t\tRIGHT JOIN CTE3 ON CTE3.c3 = CTE2.c2 and CTE3.c3 &lt;&gt; CTE1.c1\r\n\t\t\t\t\tGROUP BY CTE1.c1\r\n\t\t\t\t\tHAVING COUNT(*)&gt;1\r\n<\/pre>\n<p><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query6_Results_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1949\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query6_Results_ART.png\" alt=\"Query6_Results_ART\" width=\"580\" height=\"280\" srcset=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query6_Results_ART.png 580w, http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query6_Results_ART-300x144.png 300w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n--QUERY 7\r\nSELECT COUNT(*) FROM\r\n(SELECT COUNT(*) as c FROM sales s\r\nWHERE s.saletime BETWEEN '2008-12-01' AND '2008-12-31'\r\nGROUP BY salesid\r\nHAVING COUNT(*)=1) a\r\nLEFT JOIN\r\n(SELECT COUNT(*) as c FROM date d\r\nWHERE d.week = 1\r\nGROUP BY dateid\r\nHAVING COUNT(*)=1) b\r\nON a.c &lt;&gt; b.c\r\nLEFT JOIN\r\n(SELECT COUNT(*) as c FROM listing l\r\nWHERE l.listtime BETWEEN '2008-12-01' AND '2008-12-31'\r\nGROUP BY listid\r\nHAVING COUNT(*)=1) c\r\nON a.c &lt;&gt; c.c AND b.c &lt;&gt; c.c\r\nLEFT JOIN\r\n(SELECT COUNT(*) as c FROM venue v\r\nGROUP BY venueid\r\nHAVING COUNT(*)=1) d\r\nON a.c &lt;&gt; d.c AND b.c &lt;&gt; d.c AND c.c &lt;&gt; d.c\r\n<\/pre>\n<p><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query7_Results_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1950\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query7_Results_ART.png\" alt=\"Query7_Results_ART\" width=\"580\" height=\"280\" srcset=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query7_Results_ART.png 580w, http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query7_Results_ART-300x144.png 300w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Finally, before diving into conclusion section, a short mention of a few unexpected hiccups along the way. On a single node deployment 2 queries failed for two different reasons. First one returned an error message stating that \u2018This type of correlated subquery pattern is not supported yet\u2019 (see image below).<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query1_FAILED_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1951\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query1_FAILED_ART.png\" alt=\"Query1_FAILED_ART\" width=\"580\" height=\"560\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Because of this, I decided to remove this query from the overall results tally leaving me with 7 SQL statements for testing. Query 3 on the other hand failed with \u2018Out of memory\u2019 message on the client side and another cryptic error showing up in management console as per images below (click on image to enlarge).<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query2_FAILED_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1952\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query2_FAILED_ART.png\" alt=\"Query2_FAILED_ART\" width=\"580\" height=\"647\" srcset=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query2_FAILED_ART.png 580w, http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Query2_FAILED_ART-268x300.png 268w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query2_1_FAILED_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1992\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Query2_1_FAILED_ART.png\" alt=\"Query2_1_FAILED_ART\" width=\"580\" height=\"60\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">I think that inadequate memory allocation issue was due to the lack of resources provisioned as it only appeared when running on a single node \u2013 the multi-node deployment executed without issues. Nevertheless, it was disappointing to see Redshift not coping very well with memory allocation and management, especially given that same query run fine (albeit slow) on both of the SQL Server databases.<\/p>\n<p style=\"text-align: justify;\">For reference, below is a resource consumption graph (3 parameters included) for the multi-node deployment of Amazon Redshift during queries execution.<\/p>\n<h3 style=\"text-align: center;\"><a href=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Perf_Monitor_ALLSQL_ART.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1953\" src=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/\/2013\/11\/Perf_Monitor_ALLSQL_ART.png\" alt=\"Perf_Monitor_ALLSQL_ART\" width=\"580\" height=\"340\" srcset=\"http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Perf_Monitor_ALLSQL_ART.png 1059w, http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Perf_Monitor_ALLSQL_ART-300x176.png 300w, http:\/\/bicortex.com\/bicortex\/wp-content\/post_content\/2013\/11\/Perf_Monitor_ALLSQL_ART-1024x602.png 1024w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/a><\/h3>\n<h3 style=\"text-align: center;\">Performance Verdict<\/h3>\n<p style=\"text-align: justify;\">I don\u2019t think I have to interpret the results in much detail here \u2013 they are pretty much self-explanatory. Redshift, with the exception of few quibbles where SQL query was either unsupported or too much to handle for its default memory management, completely outrun the opposition. As I already stated in <a href=\"http:\/\/bicortex.com\/amazon-redshift-review-data-warehouse-in-the-cloud-is-here-part-1\/\" target=\"_blank\"><b>PART 1 <\/b><\/a>of this series, relational database setup is probably not the best option for reading vast volumes of data with heavy aggregations thrown into the mix (that\u2019s what SSAS is for when using Microsoft as a vendor) but at the same time I never expected such blazing performance (per dollar) from the Amazon offering. At this point I wish I had more data to throw at it as 50,000,000 records in my largest table is not really MPP database playground but nevertheless, Redshift screamed through what a gutsy SQL Server RDS deployment costing more completely chocked on. Quite impressive, although having heard other people\u2019s comments and opinions, some even going as far as saying that Redshift is a great alternative to Hadoop (providing data being structured and homogeneous), I was not surprised.<\/p>\n<p style=\"text-align: justify;\">In the next part to this series \u2013 <a href=\"http:\/\/bicortex.com\/amazon-redshift-review-data-warehouse-in-the-cloud-is-here-part-3\/\" target=\"_blank\"><b>PART 3<\/b><\/a> &#8211; I will be looking at connecting to Redshift database using some popular reporting\/data visualization tools e.g. Tableau too see if this technology makes it a viable backend solution not just for data storage but also for querying through third-party applications.<\/p>\n<p style=\"text-align: justify;\">\n","protected":false},"excerpt":{"rendered":"<p>Background And Environment Specs Recap In the FIRST part of this series I briefly explored the background of Amazon\u2019s Redshift data warehouse offering as well as outlined the environments and tools used for managing test datasets. I also recreated TICKIT database schema on all instances provisioned for testing and preloaded them with dummy data. In [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[61],"tags":[40,14,62,73,19],"class_list":["post-1941","post","type-post","status-publish","format-standard","hentry","category-cloud-computing","tag-amazon-redshift","tag-big-data","tag-cloud-computing","tag-mpp-rdbms","tag-sql-server"],"aioseo_notices":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/bicortex.com\/bicortex\/wp-json\/wp\/v2\/posts\/1941","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/bicortex.com\/bicortex\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/bicortex.com\/bicortex\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/bicortex.com\/bicortex\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/bicortex.com\/bicortex\/wp-json\/wp\/v2\/comments?post=1941"}],"version-history":[{"count":12,"href":"http:\/\/bicortex.com\/bicortex\/wp-json\/wp\/v2\/posts\/1941\/revisions"}],"predecessor-version":[{"id":2647,"href":"http:\/\/bicortex.com\/bicortex\/wp-json\/wp\/v2\/posts\/1941\/revisions\/2647"}],"wp:attachment":[{"href":"http:\/\/bicortex.com\/bicortex\/wp-json\/wp\/v2\/media?parent=1941"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/bicortex.com\/bicortex\/wp-json\/wp\/v2\/categories?post=1941"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/bicortex.com\/bicortex\/wp-json\/wp\/v2\/tags?post=1941"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}