Re: [HACKERS] [WIP] Effective storage of duplicates in B-tree index.
Peter Geoghegan <pg@bowt.ie>
Attachments
- overnight-benchmark.tar.gz (application/x-gzip)
On Tue, Dec 3, 2019 at 12:13 PM Peter Geoghegan <pg@bowt.ie> wrote: > The new criteria/heuristic for unique indexes is very simple: If a > unique index has an existing item that is a duplicate on the incoming > item at the point that we might have to split the page, then apply > deduplication. Otherwise (when the incoming item has no duplicates), > don't apply deduplication at all -- just accept that we'll have to > split the page. > the working/draft version of the patch will often avoid a huge amount of > bloat in a pgbench-style workload that has an extra index on the > pgbench_accounts table, to prevent HOT updates. The accounts primary > key (pgbench_accounts_pkey) hardly grows at all with the patch, but > grows 2x on master. I have numbers from my benchmark against my working copy of the patch, with this enhanced design for unique index deduplication. With an extra index on pgbench_accounts's abalance column (that is configured to not use deduplication for the test), and with the aid variable (i.e. UPDATEs on pgbench_accounts) configured to use skew, I have a variant of the standard pgbench TPC-B like benchmark. The pgbench script I used was as follows: \set r random_gaussian(1, 100000 * :scale, 4.0) \set aid abs(hash(:r)) % (100000 * :scale) \set bid random(1, 1 * :scale) \set tid random(1, 10 * :scale) \set delta random(-5000, 5000) BEGIN; UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; SELECT abalance FROM pgbench_accounts WHERE aid = :aid; UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); END; Results from interlaced 2 hour runs at pgbench scale 5,000 are as follows (shown in reverse chronological order): master_2_run_16.out: "tps = 7263.948703 (including connections establishing)" patch_2_run_16.out: "tps = 7505.358148 (including connections establishing)" master_1_run_32.out: "tps = 9998.868764 (including connections establishing)" patch_1_run_32.out: "tps = 9781.798606 (including connections establishing)" master_1_run_16.out: "tps = 8812.269270 (including connections establishing)" patch_1_run_16.out: "tps = 9455.476883 (including connections establishing)" The patch comes out ahead in the first 2 hour run, with later runs looking like a more even match. I think that each run didn't last long enough to even out the effects of autovacuum, but this is really about index size rather than overall throughput, so it's not that important. (I need to get a large server to do further performance validation work, rather than just running overnight benchmarks on my main work machine like this.) The primary key index (pgbench_accounts_pkey) starts out at 10.45 GiB in size, and ends at 12.695 GiB in size with the patch. Whereas with master, it also starts out at 10.45 GiB, but finishes off at 19.392 GiB. Clearly this is a significant difference -- the index is only ~65% of its master-branch size with the patch. See attached tar archive with logs, and pg_buffercache output after each run. (The extra index on pgbench_accounts.abalance is pretty much the same size for patch/master, since deduplication was disabled for the patch runs.) And, as I said, I believe that we can make this unique index deduplication stuff an internal thing that isn't even documented (maybe a passing reference is appropriate when talking about general deduplication). -- Peter Geoghegan
Commits
-
Teach pageinspect about nbtree deduplication.
- 93ee38eade1b 13.0 landed
-
Doc: Fix deduplicate_items index term.
- e537aed61db7 13.0 landed
-
Revise BTP_HAS_GARBAGE nbtree VACUUM comments.
- 4b25f5d0ba01 13.0 cited
-
Remove unneeded "pin scan" nbtree VACUUM code.
- 9f83468b3536 13.0 landed
-
Cleanup code in reloptions.h regarding reloption handling
- 50d22de9325f 13.0 cited
-
Catch invalid typlens in a couple of places
- 8557a6f10ca6 13.0 cited
-
Compute XID horizon for page level index vacuum on primary.
- 558a9165e081 12.0 cited
-
Make heap TID a tiebreaker nbtree index column.
- dd299df8189b 12.0 cited
-
Avoid pin scan for replay of XLOG_BTREE_VACUUM in all cases
- 3e4b7d87988f 9.6.0 cited
-
Revert buggy optimization of index scans
- c7111d11b188 9.6.0 cited
-
Restructure index access method API to hide most of it at the C level.
- 65c5fcd353a8 9.6.0 cited
-
Reduce pinning and buffer content locking for btree scans.
- 2ed5b87f96d4 9.5.0 cited
-
Avoid scanning nulls at the beginning of a btree index scan.
- 1a77f8b63d15 9.2.0 cited