Plan: design/IMPORT_THROUGHPUT_PLAN.md.
docs/benchmarks.md called import "about 18x slower than export" and blamed the
full insert path including index maintenance. Measuring it says that description
is wrong twice over, and the real target is different.
Measured, PG17.10 non-assert, 6,000,000 rows, 5 columns
| step |
ms |
heap INSERT INTO ... SELECT |
2,667.9 |
columnar INSERT INTO ... SELECT, no file involved |
12,989.6 |
export_arrow |
881.9 |
import_arrow |
12,150.2 |
full scan of the Parquet file through read_parquet |
1,415.0 |
import_parquet |
12,956.6 |
columnar INSERT, exhaustive selection (encoding_sample_rows = 0) |
20,103.2 |
Import is not slower than an ordinary insert: 12,150 ms against 12,990 ms for
the same rows with no file involved. There is no import-specific overhead. The
real statement is that the columnar write path is about 15x slower than the read
path, and 4.9x slower than a heap insert of the same rows, which is the wrong
direction for a format that writes about a hundredth of the bytes.
The readers are not the bottleneck: reading the whole Parquet file costs
1,415 ms, 11% of import. The other 89% is the write path.
Encoding selection is not the bulk of it either: turning sampling off costs
55% more, so what remains after sampling is a minority of the write path.
Index maintenance is not in the path at all, which is its own bug: see #153.
Where the waste is
Both readers decode a column-oriented file into per-row Datum arrays, hand each
row to table_tuple_insert, and the write path copies each value back into
per-column buffers. Arrow and PGCN are both columnar; the row exists only for the
length of one call between two column stores.
The plan proposes a batching entry point first, then column-at-a-time transfer for
the cases where the representations already agree, with the reader cost of
1,415 ms as the floor and 3 to 5 seconds as the plausible target against today's
13.
Acceptance
The claim is a ratio against the read_parquet floor rather than a millisecond
count, so it means the same thing on other hardware. Existing round-trip suites
must pass untouched, and should run against an indexed target once #153 is
resolved.
Estimated 2 to 4 dev-months for two people.
Plan:
design/IMPORT_THROUGHPUT_PLAN.md.docs/benchmarks.mdcalled import "about 18x slower than export" and blamed thefull insert path including index maintenance. Measuring it says that description
is wrong twice over, and the real target is different.
Measured, PG17.10 non-assert, 6,000,000 rows, 5 columns
INSERT INTO ... SELECTINSERT INTO ... SELECT, no file involvedexport_arrowimport_arrowread_parquetimport_parquetINSERT, exhaustive selection (encoding_sample_rows = 0)Import is not slower than an ordinary insert: 12,150 ms against 12,990 ms for
the same rows with no file involved. There is no import-specific overhead. The
real statement is that the columnar write path is about 15x slower than the read
path, and 4.9x slower than a heap insert of the same rows, which is the wrong
direction for a format that writes about a hundredth of the bytes.
The readers are not the bottleneck: reading the whole Parquet file costs
1,415 ms, 11% of import. The other 89% is the write path.
Encoding selection is not the bulk of it either: turning sampling off costs
55% more, so what remains after sampling is a minority of the write path.
Index maintenance is not in the path at all, which is its own bug: see #153.
Where the waste is
Both readers decode a column-oriented file into per-row
Datumarrays, hand eachrow to
table_tuple_insert, and the write path copies each value back intoper-column buffers. Arrow and PGCN are both columnar; the row exists only for the
length of one call between two column stores.
The plan proposes a batching entry point first, then column-at-a-time transfer for
the cases where the representations already agree, with the reader cost of
1,415 ms as the floor and 3 to 5 seconds as the plausible target against today's
13.
Acceptance
The claim is a ratio against the
read_parquetfloor rather than a millisecondcount, so it means the same thing on other hardware. Existing round-trip suites
must pass untouched, and should run against an indexed target once #153 is
resolved.
Estimated 2 to 4 dev-months for two people.