Re: tableam vs. TOAST
Robert Haas <robertmhaas@gmail.com>
From: Robert Haas <robertmhaas@gmail.com>
To: Prabhat Sahu <prabhat.sahu@enterprisedb.com>
Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2019-08-01T16:23:42Z
Lists: pgsql-hackers
Attachments
- 0004-Rename-attribute-detoasting-functions.patch (application/octet-stream) patch 0004
- 0002-Create-an-API-for-inserting-and-deleting-rows-in-TOA.patch (application/octet-stream) patch 0002
- 0003-Allow-TOAST-tables-to-be-implemented-using-table-AMs.patch (application/octet-stream) patch 0003
- 0001-Split-tuptoaster.c-into-three-separate-files.patch (application/octet-stream) patch 0001
On Tue, Jul 9, 2019 at 12:40 AM Prabhat Sahu
<prabhat.sahu@enterprisedb.com> wrote:
>> Did you run each test just once? How stable are the results?
>
> No, I have executed the test multiple times(7times each) and calculated the result as the median among those,
> and the result looks stable(with v3 patches).
I spent some time looking at your SCC test today. I think this isn't
really testing the code that actually got changed in the patch: a
quick CPU profile shows that your SCC test is bottlenecked on
pg_lzcompress, which spends a huge amount of time compressing the
gigantic string of 'a's you've constructed, and that code is exactly
the same with the patch as it in master. So, I think that any
fluctuations between the patched and unpatched results are just random
variation. There's no reason the patch should be slower with one row
count and faster with a different row count, anyway.
I tried to come up with a better test case that uses a more modest
amount of data, and ended up with this:
-- Setup.
CREATE OR REPLACE FUNCTION randomish_string(integer) RETURNS text AS $$
SELECT string_agg(random()::text, '') FROM generate_series(1, $1);
$$ LANGUAGE sql;
CREATE TABLE source_compressed (a int, b text);
INSERT INTO source_compressed
SELECT g, repeat('a', 2000) FROM generate_series(1, 10000) g;
CREATE TABLE sink_compressed (LIKE source_compressed);
CREATE TABLE source_external (a int, b text);
INSERT INTO source_external
SELECT g, randomish_string(400) FROM generate_series(1, 10000) g;
CREATE TABLE sink_external (LIKE source_external);
CREATE TABLE source_external_uncompressed (a int, b text);
ALTER TABLE source_external_uncompressed ALTER COLUMN b SET STORAGE EXTERNAL;
INSERT INTO source_external_uncompressed
SELECT g, randomish_string(400) FROM generate_series(1, 10000) g;
CREATE TABLE sink_external_uncompressed (LIKE source_external_uncompressed);
ALTER TABLE sink_external_uncompressed ALTER COLUMN b SET STORAGE EXTERNAL;
-- Test.
\timing
TRUNCATE sink_compressed, sink_external, sink_external_uncompressed;
CHECKPOINT;
INSERT INTO sink_compressed SELECT * FROM source_compressed;
INSERT INTO sink_external SELECT * FROM source_external;
INSERT INTO sink_external_uncompressed SELECT * FROM
source_external_uncompressed;
Roughly, on both master and with the patches, the first one takes
about 4.2 seconds, the second 7.5, and the third 1.2. The third one
is the fastest because it doesn't do any compression. Since it does
less irrelevant work than the other two cases, it has the best chance
of showing up any performance regression that the patch has caused --
if any regression existed, I suppose that it would be an increased
per-toast-fetch or per-toast-chunk overhead. However, I can't
reproduce any such regression. My first attempt at testing that case
showed the patch about 1% slower, but that wasn't reliably
reproducible when I did it a bunch more times. So as far as I can
figure, this patch does not regress performance in any
easily-measurable way.
Barring objections, I plan to commit the whole series of patches here
(latest rebase attached). They are not perfect and could likely be
improved in various ways, but I think they are an improvement over
what we have now, and it's not like it's set in stone once it's
committed. We can change it more if we come up with a better idea.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Commits
-
tableam: New callback relation_fetch_toast_slice.
- ce242ae154dd 13.0 landed
-
tableam: Allow choice of toast AM.
- 83322e38da1a 13.0 landed
-
Move heap-specific detoasting logic into a separate function.
- e9fd0415e6e2 13.0 landed
-
Code cleanup for toast_fetch_datum and toast_fetch_datum_slice.
- d5406dea25b6 13.0 landed
-
Rename some toasting functions based on whether they are heap-specific.
- 2e8b6bfa90b2 13.0 landed
-
Create an API for inserting and deleting rows in TOAST tables.
- bd124996ef0d 13.0 landed
-
Split tuptoaster.c into three separate files.
- 8b94dab06617 13.0 landed
-
tableam: Move heap-specific logic from needs_toast_table below tableam.
- 1171d7d58545 12.0 cited