Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nC7gt-0002Bu-S2 for pgsql-hackers@arkaria.postgresql.org; Mon, 24 Jan 2022 22:20:00 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nC7gs-00007c-G4 for pgsql-hackers@arkaria.postgresql.org; Mon, 24 Jan 2022 22:19:58 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nC7gr-00007I-Sn for pgsql-hackers@lists.postgresql.org; Mon, 24 Jan 2022 22:19:58 +0000 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1nC7gn-00053c-LE for pgsql-hackers@lists.postgresql.org; Mon, 24 Jan 2022 22:19:57 +0000 Received: by mail-wm1-x32a.google.com with SMTP id r6so294402wma.0 for ; Mon, 24 Jan 2022 14:19:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; h=message-id:date:mime-version:user-agent:subject:content-language:to :cc:references:from:in-reply-to:content-transfer-encoding; bh=7qXtoR3W1qZ6UWPnEIj0StcVg7CeeBifgMILr81N9uE=; b=XA9li5HLO7RG+mBpEZsTB/Mf+1h1PgqYpioszV65/G3j4DU/XPxyU4+wOD2HpJIjqX wh8SFR2rUg9oLGkywNAs+fcu0XcZEcVMRUoUjSdekzRo2H0xNJ5zIQy4sdLKup/72Dih Z8iB5WUsj8nME/p1cU5jCDU8P+m0SmyTzNXkiIVHxai5F2AccqEGwkkGai3a40ONaSkn oIu15mrs7AxoycLtYFecCO98xRTNuBWke41IlodTqaPsUXr5lkNa0c6KJp6W17LJFf7X a1xwsrW6hbvY7nFCP0C/s6KCSJZsWtES3mcKey7mMty4VaLR1uqD1iQafwboord5RL2h bTkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=7qXtoR3W1qZ6UWPnEIj0StcVg7CeeBifgMILr81N9uE=; b=Yc8ePwRizte8pzCC5wtstLSUlAPrU7QLNbqAq6tVbiYL2m6q6kEa2ahxsz1Dg02m8V vZeQZmb5eGgl5d5bNwiPgAjrk00u1MUtm0o1DE7KGBlM7haavHR4L1YcQnhs2bcpZjMC 6ioibxpGBdcsI6DHhPCcsLBIGsP0CX05CE5JPiypxKmvRL3cPoxWHx8qcNC2Fu7i0xXk GQVrSZSLQCAXDGSTXd8slwVVI5aWxQ0i50Sob4e4Ta28mGC1+Ui9y23yaZpj6vo+5q9n V4N6fFcn1pwZky4rvgd7JAl5cKx4sCqXTLnp7vAyf8eVhUca6Pr79rKYF4TYmHB/I1VU /1Pg== X-Gm-Message-State: AOAM532rPS49et63xHPiKB6qTjt7Az6m7cJMFmhSX09bLDahVTcsoMpX LWRvR8tD6BLsjsZn9xfRpjyBjoESeIjO6gnH5SrPyHZ33bEzvJg0trQMz+F2wyoSDUw2VBuGiPn w9Pn/Ysaut/THgL90awMZJfkiEcqAWRrPkpp7wm1cM1FAS2+i9leDu7syUZHYqHCZZtRpG+QhdU YLtdppu/CHJPrPG1O0IJKoIa6VN5ABY07JeW3NOZWP9yTj8I1oBOyn X-Google-Smtp-Source: ABdhPJzcvtSRjIalp38+VJ3GJTgaTlNe5fY10/NVy97fvunbtIG8KRBpzRX74SD/MOtz7edHPIb6eA== X-Received: by 2002:a05:600c:5107:: with SMTP id o7mr305607wms.161.1643062791971; Mon, 24 Jan 2022 14:19:51 -0800 (PST) Received: from [10.137.0.18] (ip-86-49-251-241.net.upcbroadband.cz. [86.49.251.241]) by smtp.gmail.com with ESMTPSA id i3sm14971687wru.33.2022.01.24.14.19.51 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 24 Jan 2022 14:19:51 -0800 (PST) Message-ID: Date: Mon, 24 Jan 2022 23:19:49 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.3.0 Subject: Re: Collecting statistics about contents of JSONB columns Content-Language: en-US To: Nikita Glukhov Cc: PostgreSQL Hackers , Mahendra Thalor , Oleg Bartunov , Thomas Munro References: From: Tomas Vondra In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-CLOUD-SEC-AV-Info: enterprisedb,google_mail,monitor X-CLOUD-SEC-AV-Sent: true X-Gm-Spam: 0 X-Gm-Phishy: 0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 1/23/22 01:24, Nikita Glukhov wrote: > Hi! > > I am glad that you found my very old patch interesting and started to > work on it. We failed to post it in 2016 mostly because we were not > satisfied with JSONB storage. Also we decided to wait for completion > of work on extended statistics as we thought that it could help us. > But in early 2017 we switched to SQL/JSON and forgot about this patch. > Understood. Let's see how feasible this idea is and if we can move this forward. > > I think custom datatype is necessary for better performance. With a > plain JSONB we need to do a lot of work for extraction of path stats: > - iterate through MCV/Histogram JSONB arrays > - cast numeric values to float, string to text etc. > - build PG arrays from extracted datums > - form pg_statistic tuple. > > With a custom data type we could store pg_statistic tuple unmodified > and use it without any overhead. But then we need modify a bit > VariableStatData and several functions to pass additional nullfrac > corrections. > I'm not against evaluating/exploring alternative storage formats, but my feeling is the real impact on performance will be fairly low. At least I haven't seen this as very expensive while profiling the patch so far. Of course, I may be wrong, and it may be more significant in some cases. > Maybe simple record type (path text, data pg_statistic, ext_data jsonb) > would be enough. > Maybe, but then you still need to store a bunch of those, right? So either an array (likely toasted) or 1:M table. I'm not sure it's goiing to be much cheaper than JSONB. I'd suggest we focus on what we need to store first, which seems like tha primary question, and worry about the exact storage format then. > Also there is an idea to store per-path separately in pg_statistic_ext > rows using expression like (jb #> '{foo,bar}') as stxexprs. This could > also help user to select which paths to analyze simply by using some > sort of CREATE STATISTICS. But it is really unclear how to: > * store pg_statistic_ext rows from typanalyze > * form path expressions for array elements (maybe add new jsonpath > operator) > * match various -> operator chains to stxexprs > * jsonpath-like languages need simple API for searching by stxexprs > Sure, you can do statistics on expressions, right? Of course, if that expression produces JSONB value, that's not very useful at the moment. Maybe we could have two typanalyze functions - one for regular analyze, one for extended statistics? That being said, I'm not sure extended stats are a good match for this. My feeling was we should collect these stats for all JSONB columns, which is why I argued for putting that in pg_statistic. > > > Per-path statistics should only be collected for scalars. This can be > enabled by flag JsonAnalyzeContext.scalarsOnly. But there are is a > problem: computed MCVs and histograms will be broken and we will not be > able to use them for queries like (jb > const) in general case. Also > we will not be and use internally in scalarineqsel() and var_eq_const() > (see jsonSelectivity()). Instead, we will have to implement own > estimator functions for JSONB comparison operators that will correctly > use our hacked MCVs and histograms (and maybe not all cases will be > supported; for example, comparison to scalars only). > Yeah, but maybe that's an acceptable trade-off? I mean, if we can improve estimates for most clauses, and there's a some number of clauses that are estimated just like without stats, that's still an improvement, right? > It's possible to replace objects and arrays with empty ones when > scalarsOnly is set to keep correct frequencies of non-scalars. > But there is an old bug in JSONB comparison: empty arrays are placed > before other values in the JSONB sort order, although they should go > after all scalars. So we need also to distinguish empty and non-empty > arrays here. > Hmmm ... > > > I tried to fix a major part of places marked as XXX and FIXME, the new > version of the patches is attached. There are a lot of changes, you > can see them in a step-by-step form in the corresponding branch > jsonb_stats_20220122 in our GitHub repo [1]. > Thanks! I'll go through the changes soon. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company