Open bllewell opened 4 years ago
@bllewell I was able to replicate the key issue locally. Sharing the (self-contained) SQL I used and results below.
Enable colocation and create the pgcrypto extension for gen_random_uuid()
.
CREATE DATABASE test_colocated WITH colocated = true;
\c test_colocated;
CREATE EXTENSION pgcrypto;
Using a single-tablet hash table to avoid variation due to default/starting number of tablets.
create table t_hash(
k uuid default gen_random_uuid(),
u uuid,
i int,
PRIMARY KEY (k HASH))
WITH (colocated = false)
SPLIT INTO 1 TABLETS;
\timing on
insert into t_hash(u, i) select gen_random_uuid(), generate_series from generate_series(1, 100000);
create unique index t_hash_u on t_hash(u HASH) SPLIT INTO 1 TABLETS;
create index t_hash_i on t_hash(i HASH) SPLIT INTO 1 TABLETS;
Single-tablet is default starting point for range so nothing to configure (except exclude from colocation).
create table t_range(
k uuid default gen_random_uuid(),
u uuid,
i int,
PRIMARY KEY (k ASC))
WITH (colocated = false);
\timing on
insert into t_range(u, i) select gen_random_uuid(), generate_series from generate_series(1, 100000);
create unique index t_range_u on t_range(u ASC);
create index t_range_i on t_range(i ASC);
Single-tablet (concretely a section within the colocated tablet) and range-ordered is default for colocated.
create table t_colo(
k uuid default gen_random_uuid(),
u uuid,
i int,
PRIMARY KEY (k));
\timing on
insert into t_colo(u, i) select gen_random_uuid(), generate_series from generate_series(1, 100000);
create unique index t_colo_u on t_colo(u);
create index t_colo_i on t_colo(i);
Summary is below, all values are in milliseconds.
test type \ rel type | HASH | RANGE | COLOCATED |
---|---|---|---|
load table | 3260.215 |
2935.018 |
3037.336 |
create+load uuid idx | 3428.487 |
3479.032 |
6418.028 |
create+load int idx | 2024.351 |
2054.186 |
3812.083 |
So overall, table load is more or less the same in all cases (a bit slower in hash case in this case but within regular variance during testing), while index creation (load) is very similar between hash and range, but almost ~2x slower for colocated.
Jira Link: DB-2301 The zip of my self-contained testcase is attached. I used a single node cluster on my MacBook (MacOS Mojave Version 10.14.6; Processor 2.6 GHz Intel Core i7).
Unzip and then start
0.sql
at the ysqlsh prompt. For a maximally clean start, do this before running it.Testcase outline
The testcase drops and re-creates the database using first this:
and then this
Each time after creating the database , it repeats the basic test five times to get a reasonable sample of the timings.
The basic test drops and recreates the test table, thus:
The surrogate PK column is populated using
gen_random_uuid()
rather thanserial
because timing tests (not included here) show this to be about 20x faster—as is expected.Then this timing kernel is performed:
I inherited my use of
normal_rand()
from the real context where I spotted this problem. It seems sensible to use this rather than the classicgenerate_series
just in case index creation is favored by a dense sequence of monotonically increasing integer values.Similarly, the two "value" columns with data type
double precision
andint
come from my real context. I experimented by removing theint
column. This made the slow-down ratios a bit smaller.Results
I copied-and-pasted the recorded times (see below) into a spreadsheet to compute the averages and standard deviations. Here are the answers (times in seconds):
regular database:
colocated database:
timing ratios:
I copied the timings from the terminal window into
timings.txt
, included in the zip.(Annoyingly, the timing output doesn't go to a file written with\o timings.txt
.) Copied here for the reader's convenience:Notice how the times stay fairly constant in the regular database but vary noticeably with repetition in the colocated case.
Please investigate these degrees of freedom and report the results here:
Vary the number of "value" columns from one through some reasonably large number like ten or twenty.
Single-node on laptop vs realistic 3-node deployment (e.g. on AWS or GCP).
Colocated database with regular table vs regular database with colocated table
Please note here, too, if you see the same variability in times that I show above in the colocated case after the first repeat.
Final note
On just one occasion, over several repetitions during the development of this testcase and then again in repeating the whole experiment several times, this bizarre error occurred once, during the creation of the unique index
t_dp
.