# pg_vexec brings ClickHouse MergeTree to PostgreSQL 19 as extension, hits 49 ms on ClickBench

> **Key takeaway:** A developer has integrated ClickHouse's MergeTree table engine into unmodified PostgreSQL 19 as a table access method extension, enabling a vectorized executor to achieve ClickBench geometric mean query times of 49 ms without forking the core.

**Published:** 2026-10-21T00:00:00+00:00 
**Source:** Planet PostgreSQL 
**Category:** databases-storage 
**Canonical URL:** https://fosswire.org/news/pgvexec-brings-clickhouse-mergetree-to-postgresql-19-as-exte.html 

## Summary
Igor Suhorukov has built pg_vexec, a vectorized query executor for PostgreSQL 19 implemented entirely through standard extension mechanisms with no core patches. After finding that vectorization alone yielded only 18-19% speedups due to PostgreSQL's heap storage row deformation overhead, he integrated ClickHouse's MergeTree columnar engine as a table access method. The combination dropped ClickBench geometric mean query time from 715 ms to 49 ms. The work also brings ORCA, Greenplum's cost-based optimizer, to PostgreSQL 19 via the Apache Cloudberry extension port.

## How MergeTree plugs into PostgreSQL's extension points
- **pg_vexec** implements vectorized execution nodes (VecScan, VecHashJoin, VecAgg, VecSort) that compete with standard PostgreSQL plan nodes on cost through the standard extension hooks; ORCA prices them with its own cost model
- Executor processes batches of **1,024 rows in columnar form** with kernels bound to function OIDs; falls back to stock Postgres expression interpreter where no kernel exists
- Initial vectorization on heap storage achieved only **19% improvement** (625→506 ms with standard planner, 1647→1349 ms with ORCA) because **51-86% of cycles went to deforming wide rows** from heap pages, 26-47% to page copying
- Existing PostgreSQL columnar stores (Citus columnar, Hydra) still emit **row-oriented slots through the table AM API**, preventing true columnar handoff to the vectorized executor
- MergeTree integration as a **table access method on vanilla PostgreSQL 19** enables columnar data delivery; first unoptimized version hit **148 ms**, further optimized to **49 ms** geometric mean
- Key optimization: rewriting comparison loops in **SSE2 with movemask** reduced 1,024-row comparison from 426 ns to 82 ns; a **one-line fix for missing T_TargetEntry branch** in error-throw detection eliminated 2,153,556 single-row batches in TPC-DS Q2

## Why it matters
If productionized, this could reduce operational complexity for organizations running separate OLTP and OLAP databases by bringing columnar analytical performance into PostgreSQL's transactional environment without sacrificing ACID guarantees or JOIN capabilities.