Show HN: Speeding up PostgreSQL through vectorized execution
github.com
github.com
PostgreSQL is powerful and feature-rich, and there's still so much work to be done. (Consider that index-only scans themselves are new as of 9.2!)
Very cool project.
So it's impressive, but it isn't a performance improvement for core PostgreSQL, or data stored natively in PostgreSQL (in particular, cstore_fdw is not very flexible - from the README for that project: "Note. We currently don't support updating table using INSERT, DELETE, and UPDATE commands.")
I think column-store databases are far more amenable to vectorised processing. I'm not aware of any row-store databases which do it, and most research into it has been on column-store (or hybrid) systems.
I wonder how long before postgres includes an index type optimized for in-memory workloads, e.g. a skiplist.
PGStrom uses the GPU: https://wiki.postgresql.org/wiki/PGStrom
PGOpenCL: http://wiki.postgresql.org/images/6/65/Pgopencl.pdf
PostgreSQL excels at heavy OLTP-type workloads; the MVCC architecture means that readers don't block writers, and writers don't block readers. But there is quite a lot of overhead for every row, and the query architecture is tuple-at-a-time, with lots of function calls. This means that OLAP workloads can be slow, compared to column store DBs like Vertica, MonetDB etc.
This optimization does not apply to Postgres in general, but only to citrus_fdw and other column-store foreign data wrappers.
The Postgres execution engine was designed to operate on a row-store. Even so, it can operate on a column-store via a foreign data wrapper like citrus_fdw. However, to do so it must currently reconstruct rows-at-a-time to fit its row-oriented nature. As a result, it cannot currently realize the potential performance benefits of using a column-store for certain queries.
This article is about an extension that adds some new column-at-a-time aggregate functions, then hooks into the Postgres executor to modify eligible query plans to use them. It thus enables Postgres to take advantage of the column-oriented nature of the citrus_fdw.
Is that an accurate way to look at it?
Then again, making changes for both fast column projections and aggregations in Postgres didn't look too easy. Since we told him to go crazy in a short amount of time, the best way to do that seemed through the columnar store.
Also, buried inside is the reference of the original work by VectorWise this work was based on. "Vectorization vs. Compilation in Query Execution". They don't even mention the name. Not nice IMHO.
I updated the Readme, and added a second link to the original vectorization paper. We found that most benefits came from simply switching to batch-processing; and that's why we referenced the more recent "vectorization vs LLVM" paper.
I'd say the original part of Can's work is that new ideas can be applied to PostgreSQL's robust and optimized executor, without touching any core logic. In that sense, it could also be relevant to this earlier thread on cstore: https://news.ycombinator.com/item?id=7524886
All we can do on our part is to keep working on PostgreSQL to make it even better and faster, and to share our work with others in the community.
Aside: This is a good concept to keep in mind when using channels in Go as well. When you have an overhead to moving a single unit of work through a process, and you're doing MANY of these shipments, there are savings to be had from ensuring your unit of work is large(vector/slice of items vs a single item).
There are roughly four different storage models in databases, with their own acronyms: NSM (pure row structured storage), DSM (sorted columnar structured storage), PAX (like DSM but where a row is stored within a single page), VSM (array structured individual columns where every element in a row has the same index). PAX and VSM are hybrid storage models. All four are used in real commercial systems. Vector storage models (VSM) are extremely good for real-time workloads; they sacrifice a little bit of insert performance for a major improvement in query performance relative to NSM, but their insert/append performance is much better than DSM or (to a lesser extent) PAX.
The reason vector models are extremely efficient in terms of query processing boil down to a few facts. First, a column can be streamed into the CPU as a sequential memory scan, which is very efficient. Second, constraints on multiple columns can be trivially parallelized. Third, searches across multiple columns/attributes can usually be constructed as a bitmap per column, and then composed as simple AND/OR operations over those bitmaps, which is extremely fast. Fourth, individual columns in this model are amenable to the use of vector instructions for evaluation in the CPU, saving even more clock cycles.
There is no ideal storage model, it really depends on the workload. Some sophisticated databases will change the storage model to adapt to the likely access patterns, such as NSM (great for a page with a lot of inserts) to PAX or VSM (great for queries when a page is unlikely to change much).
Not all columnar formats have great CPU streaming performance and even then it is data type dependent. Many columnar formats have significantly worse streaming performance than vector formats because only the latter is primarily optimized for it and column stores will trade that for other things (like format compressibility). And for data types that have no mathematical order of any kind e.g. interval data types, columnar formats effectively degenerate into very inefficient vector formats. It is still an open academic discussion.
That would be an amazing performance improvement.
[1] http://www.pgcon.org/2014/schedule/attachments/322_IMCS.pdf