Re: Pg_locks and pg_stat_activity

2020-12-04 Thread aditya desai
Hi Kyotaro,
Many thanks for the response. Will try and debug further. Have responded to
Justin in another chain. Could you please check and advise if anything ?

Regards,
Aditya.

On Fri, Dec 4, 2020 at 1:23 PM Kyotaro Horiguchi 
wrote:

> At Fri, 4 Dec 2020 12:11:59 +0530, Ravikumar Reddy <
> urravikumarre...@gmail.com> wrote in
> > Hi,
> > pg_stat_activity -- Providers the active and ideal connection for our
> > database
> > Pg_locks   --  Provider the queries/procedure/function details if
> > any object is locked at the current in our database.
>
> Yeah..
>
> That result is quite hard to see, but..
>
> > On Fri, Dec 4, 2020 at 11:43 AM aditya desai  wrote:
> >
> > > Hi Postgres Experts,
> > > Requesting for advice on below. I am new to postgres :(
> > >
> > > Regards,
> > > Aditya.
> > >
> > > On Tue, Dec 1, 2020 at 9:41 PM aditya desai 
> wrote:
> > >
> > >> Hi,
> > >> One of the API is calling three of the below queries. Output(jobids)
> of
> > >> 1st query gets fed to 2nd query in API.
> > >>
> > >> Query 1:
> > >>
> > >> select j.id from job j where $19=$20 and j.internaljobcode in
> > >> ($21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31)  and j.countrycode =
> $1  and
> > >> j.facilitycode in ($2) and j.jobstatuscode in ($3, $4, $5, $6) and
> > >> j.internaljobcode in ($7, $8, $9, $10, $11, $12, $13, $14, $15)  and
> > >> ((j.jobstartdatetime between $16 and $17) or j.jobstartdatetime IS
> NULL)
> > >> ORDER BY createddate DESC limit $18"
> > >>
> > >> Query 2
> > >>
> > >> with JobData AS ( select * from job where id in ($1, $2, $3, $4, $5,
> $6,
> > >> $7, $8, $9, $10) )
> > >> select j.id
> > >>
> ,j.jobcategory,j.internaljobcode,j.jobname,j.jobstatuscode,j.jobreferencenumber,
> > >>
> > >>
> vws.vascodes,j.createddate,j.facilitycode,j.countrycode,j.sladate,j.codamount,j.jobstartdatetime,j.jobenddatetime,j.attemptcount,
> > >> j.primeindicator,j.rescheduleddatetime,j.jobproductcode,
> > >> j.tour_id, j.pickupaccount,
> > >>
> j.connoterequired,j.expectedbags,j.expectedparcels,j.isservicepointpickup,
> > >>
> > >>
> j.estimateddeliverydatetime,j.currency,j.paymentmethod,j.paymentamount,j.missorted,j.pickupcustomername,j.mps,j.parcelcount,j.jobcontactpersonname,t.courier_id,t.tourid,
> > >> js.jobstatusname, jt.externaljobcode, ja.city, ja.postalcode,
> > >> ja.addressline1, ja.addressline2,
> > >> ja.addressline3,ja.addresstype, ja.state
> > >> from JobData j join jobaddress ja on ja.job_id=j.id join
> > >> jobstatus js on js.jobstatuscode=j.jobstatuscode
> > >> join jobtype jt on j.internaljobcode=jt.internaljobcode
> left
> > >> join
> > >> (select v.job_id, string_agg(distinct(v.code),'PPOD') as
> > >> vascodes from JobData j  join valueaddedservices v on j.id=v.job_id
> > >> group by v.job_id) AS vws on vws.job_id=j.id left join tour t on t.id
> =j.tour_id
> > >> and ((j.internaljobcode in ('003','012') and ja.addresstype='RETURN')
> or
> > >> j.internaljobcode not in ('003','012')) ORDER BY id DESC ;
> > >>
> > >> Query3:
> > >>
> > >> "with JobCount as ( select jobstatuscode,count($14) stat_count from
> job j
> > >> where $15=$16  and j.countrycode = $1  and j.facilitycode in ($2) and
> > >> j.internaljobcode in ($3, $4, $5, $6, $7, $8, $9, $10, $11)  and
> > >> ((j.jobstartdatetime between $12 and $13) or j.jobstartdatetime IS
> NULL)
> > >> group by j.jobstatuscode)
> > >> select js.jobstatuscode,COALESCE(stat_count,$17) stat_count from
> JobCount
> > >> jc right outer join jobstatus js on jc.jobstatuscode=js.jobstatuscode"
> > >>
> > >>
> > >> When I run explain analyze for 1st two queries Execution Time is
> below 1
> > >> milliseconds for these queries. Basically queries run fast and with
> low
> > >> cost when ran from Database 'psql' or pgadmin. However when called
> from API
> > >> Average Time in pg_stat_statements shows more than 1 second. When
> Load test
> > >> runs these queries get concurrently called ,response time beomes poor
> with
> > >> more load. Could this be due to Lockings.
> > >>
> > >>
> > >> I checked pg_locks and I see the below records. Query that I used is
> also
> > >> given below. I could see few ExclusiveLocks for "virtualxid" records
> and
> > >> for queries with CTEs(WITH Clause). Please advise
> > >>
> > >>
> > >>
> > >> SELECT * FROM pg_locks pl LEFT JOIN pg_stat_activity psa
> > >> ON pl.pid = psa.pid;
>
> 
>
> You would find that the "granted" column in all the rows from pg_locks
> is "true", that is, no one is waiting on a lock. That slowdown doesn't
> at least seem coming from lock conflict.
>
> regards.
>
> --
> Kyotaro Horiguchi
> NTT Open Source Software Center
>


Re: Pg_locks and pg_stat_activity

2020-12-04 Thread Justin Pryzby
On Fri, Dec 04, 2020 at 01:31:14PM +0530, aditya desai wrote:
> Hi Justin,
> Many thanks for your response. Please see my response below.
> 
> What do you mean by API ?  If it's a different client, how does it connect ?
> Queries are getting called from Web UI built in Microservices spring boot.
> It connected to Database with JDBC driver. Developers have handled
> connection pooling at the Application side.
> 
> What db driver ?
> 
> Driver is JDBC

I suspect JDBC is using parameterized queries (postgres $1, $2, ..) and psql
isn't (unless you type "prepare p AS SELECT ..." and execute p(.., .., ..)"

You can search and find other people who reported similar issues.
https://www.postgresql.org/message-id/flat/A737B7A37273E048B164557ADEF4A58B50FB8D5E%40ntex2010i.host.magwien.gv.at
https://www.postgresql.org/message-id/flat/20200504191201.GU28974%40telsasoft.com

I don't know what server version you have, so I don't know whether to suggest
testing with plan_cache_mode=force_custom_plan

-- 
Justin




Re: Pg_locks and pg_stat_activity

2020-12-04 Thread aditya desai
Hi Justin,
Thanks for your response.
I suspect JDBC is using parameterized queries (postgres $1, $2, ..) and psql
isn't (unless you type "prepare p AS SELECT ..." and execute p(.., .., ..)"

Yes JDBC is using parameterized queries which get constructed dynamically
depending upon user privileges in the application.Does this cause any
issues?

I don't know what server version you have, so I don't know whether to
suggest
testing with plan_cache_mode=force_custom_plan

It's Postgres 11.5.

I will look into links you shared.

Regards,
AD.

On Fri, Dec 4, 2020 at 1:47 PM Justin Pryzby  wrote:

> On Fri, Dec 04, 2020 at 01:31:14PM +0530, aditya desai wrote:
> > Hi Justin,
> > Many thanks for your response. Please see my response below.
> >
> > What do you mean by API ?  If it's a different client, how does it
> connect ?
> > Queries are getting called from Web UI built in Microservices spring
> boot.
> > It connected to Database with JDBC driver. Developers have handled
> > connection pooling at the Application side.
> >
> > What db driver ?
> >
> > Driver is JDBC
>
> I suspect JDBC is using parameterized queries (postgres $1, $2, ..) and
> psql
> isn't (unless you type "prepare p AS SELECT ..." and execute p(.., .., ..)"
>
> You can search and find other people who reported similar issues.
>
> https://www.postgresql.org/message-id/flat/A737B7A37273E048B164557ADEF4A58B50FB8D5E%40ntex2010i.host.magwien.gv.at
>
> https://www.postgresql.org/message-id/flat/20200504191201.GU28974%40telsasoft.com
>
> I don't know what server version you have, so I don't know whether to
> suggest
> testing with plan_cache_mode=force_custom_plan
>
> --
> Justin
>


Index for range queries on JSON (user defined fields)

2020-12-04 Thread Marco Colli
Hello!

We have a multi-tenant service where each customer has millions of users
(total: ~150M rows). Now we would like to let each customer define some
custom columns for his users and then let the customer search his users
efficiently based on these columns.

This problem seems really hard to solve with PostgreSQL:
https://stackoverflow.com/questions/5106335/how-to-design-a-database-for-user-defined-fields

In particular the easiest way would be to add a JSON field on the users
table (e.g. user metadata). However the PostgreSQL GIN index only supports
exact matches and not range queries. This means that a query on a range
(e.g. age > 30) would be extremely inefficient and would result in a table
scan.

Algorithmically it seems possible to use a GIN index (based on btree) for a
range query. Also MongoDB seems to support something similar (
https://docs.mongodb.com/manual/core/index-wildcard/).

Are there any plans to add support for range queries to GIN indexes (on
JSON) in the future versions of PostgreSQL?


Marco Colli
Pushpad


PostgeSQL JSONB Column with various type of data

2020-12-04 Thread Riswana Rahman
Hi Team,

We are using Postgresql JSONB as storage type in our development.
In the below table , RECORD column has JSONB data and we create a view which 
will derive the column "TEST_MV_2" from column "RECORD" as below

CREATE OR REPLACE VIEW public."V_TEST_SELECT"
AS
   SELECT a.recid,a.record AS "RECORD",
   jsonb_path_query(a.xmlrecord, '$."2"'::jsonpath) AS "TEST_MV_2 "
   FROM " TEST_SELECT " a;

So we might have array of data or an empty JSON object or an array of empty 
JSON object or a string in the column "TEST_MV_2".
Null is stored as empty JSON object due to our business logic.

RECID
RECORD (datatype: JSONB)
TEST_MV_2 (datatype: JSONB)
"SELTEST1"
"{"1": "SELTEST1", "2": [{"": "TESTVALUE"}, {}]}"
[{"": "TESTVALUE"}, {}]
"SELTEST2"
"{"1": "SELTEST2", "2": "TESTVALUE"}"
"TESTVALUE"
"SELTEST3"
"{"1": "SELTEST3", "2": [{"": "TESTVALUE"}, {"": "TESTVALUE1"}]}"
[{"": "TESTVALUE"}, {"": "TESTVALUE1"}]
"SELTEST4"
"{"1": "SELTEST4", "2": [{"": "TESTVALUE4MV1"}, {}]}"
[{"": "TESTVALUE4MV1"}, {}]
"SELTEST5"
"{"1": "SELTEST5", "2": [{}, {}]}"
[{},{}]
"SELTEST6"
"{"1": "SELTEST6", "2": {}}"
{}
"SELTEST7"
"{"1": "SELTEST7", "2": [{}, {"": "TESTVALUE"}]}"
[{}, {"": "TESTVALUE"}]


In such cases, to find the null values in the JSONB, I have written below SQL 
Function to handle different type of data

CREATE OR REPLACE FUNCTION jsonbNull(jsonb_column JSONB)
returns boolean as $$
declare
  isPoint text := jsonb_typeof(jsonb_column) ;
begin
  CASE isPoint
 WHEN 'array' THEN
   if  true = ALL(select 
(jsonb_array_elements(jsonb_column)) = '{}') THEN
  return true;
   else
   return false;
   end if;
WHEN 'object' THEN
   if jsonb_column = '{}' THEN
  return true;
   else
  return false;
   end if;
 WHEN 'string' THEN
  return false;
 ELSE
   return true;
  END CASE;
end;
$$ LANGUAGE plpgsql IMMUTABLE;

Sample SQL statement used:
SELECT RECID,"TEST_MV_2" FROM "V_TEST_SELECT" WHERE true=jsonbNull("TEST_MV_2") 
 ORDER BY RECID ;


I would like to know whether we can handle multiple types of JSONB data in a 
better/nicer way as this function could impact performance of the query.

Kindly provide your suggestions.

Thanks,
[cid:image001.png@01D46E21.E2244170]
RISWANA
Technical Lead

TEMENOS India
Sterling Road, Chennai
d: + 91 9943613190

[cid:image002.png@01D45B44.8C6E0030][cid:image003.png@01D45B3E.3EA72B70][cid:image004.png@01D45B3E.3EA72B70][cid:image005.png@01D45B3E.3EA72B70]
  
temenos.com




The information in this e-mail and any attachments is confidential and may be 
legally privileged. It is intended solely for the addressee or addressees. Any 
use or disclosure of the contents of this e-mail/attachments by a not intended 
recipient is unauthorized and may be unlawful. If you have received this e-mail 
in error please notify the sender. Please note that any views or opinions 
presented in this e-mail are solely those of the author and do not necessarily 
represent those of TEMENOS. We recommend that you check this e-mail and any 
attachments against viruses. TEMENOS accepts no liability for any damage caused 
by any malicious code or virus transmitted by this e-mail.


Re: PostgeSQL JSONB Column with various type of data

2020-12-04 Thread Michael Lewis
On Fri, Dec 4, 2020 at 9:21 AM Riswana Rahman  wrote:

> CREATE OR REPLACE FUNCTION jsonbNull(jsonb_column JSONB)
>
> returns boolean as $$
>
> declare
>
>   isPoint text := jsonb_typeof(jsonb_column) ;
>
> begin
>
>   CASE isPoint
>
>  WHEN 'array' THEN
>
>if  true = ALL(select
> (jsonb_array_elements(jsonb_column)) = '{}') THEN
>
>   return true;
>
>else
>
>return false;
>
>end if;
>
> WHEN 'object' THEN
>
>if jsonb_column = '{}' THEN
>
>   return true;
>
>else
>
>   return false;
>
>end if;
>
>  WHEN 'string' THEN
>
>   return false;
>
>  ELSE
>
>return true;
>
>   END CASE;
>
> end;
>
> $$ LANGUAGE plpgsql IMMUTABLE;
>

As far as I can tell, it seems like this could be re-written as a function
in SQL instead of plpgsql which allows for it to be in-lined. Have you
tested performance and found it to be an issue, or just optimizing in
advance of a need?

>


Re: Index for range queries on JSON (user defined fields)

2020-12-04 Thread Nick Cleaton
On Fri, 4 Dec 2020 at 15:39, Marco Colli  wrote:

> Hello!
>
> We have a multi-tenant service where each customer has millions of users
> (total: ~150M rows). Now we would like to let each customer define some
> custom columns for his users and then let the customer search his users
> efficiently based on these columns.
>
> This problem seems really hard to solve with PostgreSQL:
>
> https://stackoverflow.com/questions/5106335/how-to-design-a-database-for-user-defined-fields
>
> In particular the easiest way would be to add a JSON field on the users
> table (e.g. user metadata). However the PostgreSQL GIN index only supports
> exact matches and not range queries. This means that a query on a range
> (e.g. age > 30) would be extremely inefficient and would result in a table
> scan.
>

You could have a table of (tenant, customer, setting_name, setting_value)
so that a btree index on (tenant, setting_name, setting_value) would work
for "select customer from my_table where tenant=$1 and setting_name='age'
and setting_value > 30"

That doesn't deal with setting values having a variety of types, but you
could have a distinct user defined settings table for each setting value
type that you want to support.