Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hUdnx-0001Sj-L6 for pgsql-performance@arkaria.postgresql.org; Sat, 25 May 2019 21:02:14 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1hUdnw-0005ZZ-6G for pgsql-performance@arkaria.postgresql.org; Sat, 25 May 2019 21:02:12 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hUdnv-0005SD-ME for pgsql-performance@lists.postgresql.org; Sat, 25 May 2019 21:02:11 +0000 Received: from mail-wm1-x32c.google.com ([2a00:1450:4864:20::32c]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hUdnp-0003ss-4d for pgsql-performance@lists.postgresql.org; Sat, 25 May 2019 21:02:11 +0000 Received: by mail-wm1-x32c.google.com with SMTP id i3so12518058wml.4 for ; Sat, 25 May 2019 14:02:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=subject:to:references:from:openpgp:autocrypt:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=xkaIXZUZFjzLV4hVtEO8+Xk4TBo7rg8xrYpuJC0RAls=; b=cl4GxhZepy7joogEzuoBmZ+VUoPFVFi43JHWyfT5HD/gPlHt7QW0PPqcTUcEaamHfP mFcn4ZjO/Y363Lq+3tIDLT/o38iCKhaBonC0SHXSfJVDGlF6lmNit/5KDC1nH+5Ts8Qg mpohBZdFySpRcxCfe4mWc+9sOSmQ7qllG2x/5RmPvMVlAE57UD3muEhsnTV0wfmBT8Bt 0VdYTepfXTvzF6+I1bwAmT24fzUPCEqhMGdVkvHSqVFWkYfD3RhbOkUTUXYGptXweT2H pwR4F/fo9U0sZ96NPsLyCik3YHQ7t7y0vVc5wUOlgRYyCLR9Jm/8rsnqVAMXIuj/nV4/ levg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:openpgp:autocrypt :message-id:date:user-agent:mime-version:in-reply-to :content-language:content-transfer-encoding; bh=xkaIXZUZFjzLV4hVtEO8+Xk4TBo7rg8xrYpuJC0RAls=; b=S+bLh73TVnAMU7S/BHUdwOl7pNWL36bXzLlXmiI9vFoFO8yHKqTPJNTo4D19bwuqxG sJtn0IdqhGYLkL/nK6ZuCsaKYbrVxGrvR9dXKBYIpEBAbY1lD7kVBugbe4zglCT26fNd 7XvhlFQT5JsUJdHwnzj+r4SfPjABNBy4UG4n9hhsiOJhLlR20f80jX7hyc7ipCeYBkn7 oc0v1szwE0vRdptF+4OKT/U2GvEeghAvHqbneEHjJg8lkJiFl6Vjyt+mpGlSK6e072DT jTg/iXzXznccuKLj07Aivc2bNbShSD5VdJTOwbEQP+Zznh1NjpdHmaCaE94UetYzuqZ8 q6uA== X-Gm-Message-State: APjAAAXxSsLeovjCPpVTbAo8WKOi5vU6rf57zgcPFj9Hz0aGYBHL4Gm8 vi0GG8KCX89q1Bbz7e8NMdbqdsLp X-Google-Smtp-Source: APXvYqwdFt2suKAxmHhI6xqs5+mPPC024imr7GWWPhzr1jXbUHcaInPsv7E2BW81AwfSoUUrIQ1Tdw== X-Received: by 2002:a1c:d14b:: with SMTP id i72mr4161688wmg.4.1558818122632; Sat, 25 May 2019 14:02:02 -0700 (PDT) Received: from [192.168.66.78] (pD9582420.dip0.t-ipconnect.de. [217.88.36.32]) by smtp.googlemail.com with ESMTPSA id n4sm6677631wrp.61.2019.05.25.14.02.01 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 May 2019 14:02:01 -0700 (PDT) Subject: Re: UUID v1 optimizations... To: pgsql-performance@lists.postgresql.org References: <8d5f4b67-d540-8d3d-9979-808b9c1e1ca7@googlemail.com> <20635.1558796270@sss.pgh.pa.us> <19faa3aa-a103-b991-ff20-b73852085f30@googlemail.com> From: Ancoron Luciferis Openpgp: preference=signencrypt Autocrypt: addr=ancoron.luciferis@googlemail.com; prefer-encrypt=mutual; keydata= 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 jG7LftY+nte9Tt8CTQ== Message-ID: <4fbe7a6a-79f7-fd64-667b-df0808060a89@googlemail.com> Date: Sat, 25 May 2019 23:02:01 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 25/05/2019 21:00, Vitalii Tymchyshyn wrote: > I am not sure why do you want to change on-disk storage format? If we > are talking about indexes, it's more about comparison function (opclass) > that is used in an index.  > Am I wrong? I don't "want" to change the on-disk format of the v1 UUID's but that seems to be the most efficient approach to me (if anyone would ever want to implement that) as not changing it would mean to introduce the unshuffling of the timestamp bytes in a lot of other places where it would decrease the performance instead of increasing it, not to speak of VACUUM, REINDEX, CLUSTER, .... One of my use-cases would also benefit a lot here when trying to find entries that have been created within a given time range. To do that (without an additional timestamp column), I'd end up with a full index scan to determine the rows to read as there is no correlation between those (timestamp and value sort order). For example I would like to query the DB with: WHERE id >= '7d9c4835-5378-11ec-0000-000000000000' AND id < '5cdcac78-5a9a-11ec-0000-000000000000' ...which is impossible atm. I have written myself a helper function that extracts the timestamp, but that is executed (of course) for each and every entry while filtering or increases (if used as an index expression) the write RTT by quite a lot (if you're dealing with peak-load style applications like we have): WHERE time_part_uuidv1(id) >= '2021-12-02 14:02:31.021778+00' AND time_part_uuidv1(id) < '2021-12-11 15:52:37.107212+00' So, although possible, it is not really an option for an application like we have (and we don't just want to throw hardware at it). I don't know if all that makes any sense to you or if I'm just missing a piece of the puzzle inside the PostgreSQL code base. If I do, please tell me. :) Cheers, Ancoron > > сб, 25 трав. 2019 о 11:21 Ancoron Luciferis > > пише: > > On 25/05/2019 16:57, Tom Lane wrote: > > Ancoron Luciferis > writes: > >> So I investigated the PostgreSQL code to see how it is handling > UUID's > >> with respect to storage, sorting, aso. but all I could find was > that it > >> basically falls back to the 16-byte. > > > > Yup, they're just blobs to us. > > > >> After struggling to find a way to optimize things inside the > database, I > >> reverted to introduce a hack into the application by not > shuffling the > >> timestamp bytes for the UUID's, which makes it look quite serial in > >> terms of byte order. > > > >> So, my question now is: Would it make sense for you to handle these > >> time-based UUID's differently internally? Specifically > un-shuffling the > >> timestamp before they are going to storage? > > > > No, because > > > > (1) UUID layout is standardized; > > You mean the presentation at the byte-level is. ;) > > > > > (2) such a change would break on-disk compatibility for existing > > databases; > > Yes, that certainly is a show-stopper. > > > > > (3) particularly for the case of application-generated UUIDs, we do > > not have enough information to know that this would actually do > anything > > useful; > > Well, not only the layout is standardized, but also there is a semantic > to it depending on the version. Specifically for version 1, it has: > 1. a timestamp > 2. a clock sequence > 3. a node id > > Ans as PostgreSQL already provides this pretty concrete data type, it > could be a natural consequence to also support the semantic of it. > > E.g. the network types also come with a lot of additional operators and > functions. So I don't see a reason not to respect the additional > capabilities of a UUID. > > For other versions of UUID's, functions like timestamp would certainly > not be available (return NULL?), respecting the concrete semantic. > > > > > (4) it in fact *wouldn't* do anything useful, because we'd still have > > to sort UUIDs in the same order as today, meaning that btree index > behavior > > would remain the same as before.  Plus UUID comparison would get a lot > > more complicated and slower than it is now. > > I get your first sentence, but not your second. I know that when > changing the internal byte order we'd have to completed re-compute > everything on-disk (from table to index data), but why would the sorting > in the index have to be the same? > > And actually, comparison logic wouldn't need to be changed at all if the > byte order is "changed" when the UUID is read in when reading the > representation into the internal UUID's byte array. > > Function: > string_to_uuid(const char *source, pg_uuid_t *uuid); > > ^^ here I would apply the change. And of course, reverse it for > generating the textual representation. > > That would slow down writes a bit, but that shouldn't be the case > because index insertions are speed up even more. > > But still, on-disk change is still a show-stopper, I guess. > > > > > (5) even if we ignored all that and did it anyway, it would only help > > for version-1 UUIDs.  The index performance issue would still > remain for > > version-4 (random) UUIDs, which are if anything more common than v1. > > Yes, I am aware that the changes might be of very limited gain. V4 > UUID's are usually used for external identifiers. For internal ones, > they don't make sense to me (too long, issues with randomness/enthropie > under high load, ...). ;) > > I just recently used these UUID's also together with a function for > TimescaleDB auto-partitioning to provide the timestamp for the > partitioning logic instead of the need for a separate timestamp column. > > This is also one of the reasons why I was also asking for native support > functions to extract the timestamp. I am apparently not very good at C > so I am currently using Python and/or PgPLSQL for it, which is > pretty slow. > > > > > > > FWIW, I don't know what tool you're using to get those "bloat" > numbers, > > but just because somebody calls it bloat doesn't mean that it is. > > The normal, steady-state load factor for a btree index is generally > > understood to be about 2/3rds, and that looks to be about what > > you're getting for the regular-UUID-format index.  The fact that the > > serially-loaded index has nearly no dead space is because we hack the > > page split logic to make that happen --- but that is a hack, and it's > > not without downsides.  It should *not* be taken to be an indication > > of what you can expect for any other insertion pattern. > > OK, understood. I was actually a bit surprised by those numbers myself > as these "serial" UUID's still only have the timestamp bytes in > ascending order, the clock sequence and node is still pretty random (but > not inside a single transaction, which might help the hack). > > > > > The insertion-speed aspect is a real problem, but the core of that > problem > > is that use of any sort of standard-format UUID turns applications > that > > might have had considerable locality of reference into > applications that > > have none.  If you can manage to keep your whole index in RAM that > would > > not hurt too much, but as soon as it doesn't fit you have a problem. > > When your app has more or less predictable reference patterns it's > best > > to design a unique key that matches that, instead of expecting that > > essentially-random keys will work well. > > The system was configured to have more than enough space for the index > and table data to fit into memory, but I am not sure. How can I verify > that? An EXPLAIN on the INSERT apparently doesn't include index > insertion. > > > > > Or in short, hacking up the way your app generates UUIDs is exactly > > the right way to proceed here. > > OK. Glad to hear that. > > One last question, though: > Would it make sense to create a specialized UUID v1 type (e.g. with an > extension) that does the transformation and delegates for all other > things to the existing UUID type support? > > > > >                       regards, tom lane > > > >