|
From: Manikandan S. <ma...@vt...> - 2015-06-04 03:57:26
|
Hi, Please see below
\d+ Table1
Table "Table1"
Column | Type | Modifiers | Storage | Stats
target | Description
--------------+-----------------------+-----------+----------+--------------+-------------
id | numeric | | main | 1000
|
age | numeric | | main | 1000
|
gender | numeric | | main | 1000
|
col1 | character varying(5) | | extended | 1000
|
Indexes:
"index_age_table1" btree (age)
"index_col1_table1" btree (col1)
"index_gender_table1" btree (gender)
"index_id_table1" btree (id)
Has OIDs: no
Distribute By: HASH(id)
Location Nodes: ALL DATANODES
\d+ Table2
Table "Table2"
Column | Type | Modifiers | Storage | Stats target |
Description
-----------------+---------+-----------+---------+--------------+-------------
id | numeric | | main | 1000 |
rep | numeric | | main | 1000 |
time | numeric | | main | 1000 |
Indexes:
"index_time_table2" btree (time)
"index_id_table2" btree (id)
"index_rep_table2" btree (rep)
Has OIDs: no
Distribute By: HASH(id)
Location Nodes: ALL DATANODES
Explain verbose of the query:
GroupAggregate (cost=0.07..0.10 rows=1 width=56)
Output: d.col1, round(((count(d.id) / 10))::double precision)
-> Sort (cost=0.07..0.08 rows=1 width=56)
Output: d.col1, d.id
Sort Key: d.col1
-> Hash Join (cost=0.01..0.06 rows=1 width=56)
Output: d.col1, d.id
Hash Cond: (d.id = i.id)
-> Data Node Scan on Table1 "_REMOTE_TABLE_QUERY_"
(cost=0.00..0.00 rows=1000 width=56)
Output: d.col1, d.id
Node/s: datanode_c2_d1, datanode_c3_d1,
datanode_c4_d1, datanode_c5_d1
Remote query: SELECT col1, id FROM ONLY Table1 d
WHERE true
-> Hash (cost=0.00..0.00 rows=1000 width=32)
Output: i.id
-> Data Node Scan on Table2 "_REMOTE_TABLE_QUERY_"
(cost=0.00..0.00 rows=1000 width=32)
Output: i.id
Node/s: datanode_c2_d1, datanode_c3_d1,
datanode_c4_d1, datanode_c5_d1
Remote query: SELECT id, time FROM ONLY
Table2 i WHERE true
Coordinator quals: (((i.time)::double
precision <= trunc(((('now'::cstring)::date - to_date('01 Jan
2000'::text, 'DD Mon YYYY'::text)))::double precis
ion)) AND ((i.time)::double precision >=
trunc(((((('now'::cstring)::date - to_date('01 Jan 2000'::text, 'DD Mon
YYYY'::text)) + 1) - 365))::double precision)))
Also, one weird thing that I noticed is if I don't give the 'trunc()'
date manipulation in the query and just gave some valid numbers in the
between clause like 'between 5266 and 5632', am getting a different
query plan and the query executes in just a few seconds. The following
is the query planner output when I give the numbers directly in the
between clause.
GroupAggregate (cost=49.83..57.35 rows=1 width=56)
Output: d.col1, round(((count((count(d.id))) / 10))::double
precision)
-> Sort (cost=49.83..52.33 rows=1000 width=56)
Output: d.col1, (count(d.id))
Sort Key: d.col1
-> Data Node Scan on "__REMOTE_GROUP_QUERY__"
(cost=0.00..0.00 rows=1000 width=56)
Output: d.col1, (count(d.id))
Node/s: datanode_c2_d1, datanode_c3_d1, datanode_c4_d1,
datanode_c5_d1
Remote query: SELECT l.a_1, count(l.a_2) FROM ((SELECT
d.col1, d.id FROM ONLY Table1 d WHERE true) l(a_1, a_2) JOIN (SELECT
i.id FROM ONLY Table2 i WHERE ((i.time >= 5266::numeric) AND (i.time <=
5632::numeric))) r(a_1) ON (true)) WHERE (l.a_2 = r.a_1) GROUP BY 1
ORDER BY 1 DESC
But my requirement is with the trunc() date manipulation.
Thanks
On Wed, 2015-06-03 at 18:08 -0700, Abbas Butt wrote:
>
>
>
>
> On Wed, Jun 3, 2015 at 5:10 PM, Manikandan Soundarapandian
> <ma...@vt...> wrote:
>
> Hi Abbas,
>
> I just looked at the planner for the query that am running.
> This is the query that am running,
>
> SELECT d.col1 RVALUE, ROUND(COUNT(d.col2)/10) COUNT FROM
> Table1 d, Table2 i WHERE d.id=i.id AND i.time BETWEEN
> TRUNC(CURRENT_DATE-TO_DATE('01 Jan 2000','DD Mon YYYY')+1-365)
> AND TRUNC(CURRENT_DATE-TO_DATE('01 Jan 2000','DD Mon YYYY'))
> GROUP BY d.col1 ORDER BY d.col1 DESC;
>
> And the query plan for a configuration with 4 datanodes and 1
> coordinator,
>
> GroupAggregate (cost=0.07..0.10 rows=1 width=56)
> -> Sort (cost=0.07..0.08 rows=1 width=56)
> Sort Key: d.col1
> -> Hash Join (cost=0.01..0.06 rows=1 width=56)
> Hash Cond: (d.id = i.id)
> -> Data Node Scan on Table1
> "_REMOTE_TABLE_QUERY_" (cost=0.00..0.00 rows=1000 width=56)
> Node/s: datanode_c2_d1, datanode_c3_d1,
> datanode_c4_d1, datanode_c5_d1
> -> Hash (cost=0.00..0.00 rows=1000 width=32)
> -> Data Node Scan on Table2
> "_REMOTE_TABLE_QUERY_" (cost=0.00..0.00 rows=1000 width=32)
> Node/s: datanode_c2_d1,
> datanode_c3_d1, datanode_c4_d1, datanode_c5_d1
> Coordinator quals:
> (((i.time)::double precision <= trunc(((('now'::cstring)::date
> - to_date('01 Jan 2000'::text, 'DD Mon YYYY'::text)))::double
> precisio
> n)) AND ((i.time)::double precision >=
> trunc(((((('now'::cstring)::date - to_date('01 Jan
> 2000'::text, 'DD Mon YYYY'::text)) + 1) - 365))::double
> precision)))
>
>
> Table1 contains 22 million records and Table2 contains 10
> million records.
> This query took several minutes (almost 35) to get results and
> one third of that time is spent in FetchTuple. Do you see
> something wrong with the query plan?
>
>
>
> Can you provide output of
>
> \d+ Table1
> \d+ Table2
>
> I am interested in the distribution column of the tables.
>
>
> Also please provide the output of EXPLAIN VERBOSE on the query.
>
>
>
>
>
>
> Since the multiplexed IO isn't the real bottleneck here, my
> proposal would be to change the way how populating the
> TupleStore at the coordinator is working and introduce
> parallelism there. Is this a right direction? Please let me
> know your thoughts.
>
> Thanks
> Mani
>
>
>
> On Wed, 2015-06-03 at 01:49 -0700, Abbas Butt wrote:
>
> >
> >
> > On Tue, Jun 2, 2015 at 10:17 PM, Manikandan Soundarapandian
> > <ma...@vt...> wrote:
> >
> > Hi Abbas,
> >
> > Thanks for the reply. I understand how
> > pgxc_node_receive is working to
> > get incoming data from the datanodes.
> > Yes, I have made experiments to study the
> > postgres-xc system in a setup
> > with 12 datanodes and a coordinator and performed
> > join, groupby and
> > order by operations on two tables with around 20
> > million and 10 million
> > records respectively. I have found that around
> > 20-30% of the time is
> > spent in the 'FetchTuple' method which reads into
> > the provided tupleslot
> > one datarow at a time from the combiner's buffer
> > which is in turn filled
> > by the pgxc_node_receive method.
> >
> >
> > XC planner pushes parts of query processing to datanodes to
> > speed things up.
> >
> > In the queries you tried, did the query planner perform this
> > optimization?
> >
> > If not then you can gain advantage by improving the planner
> > to generate optimized plans that avoid UN-necessary
> > materialization at the coordinator.
> >
> > This will bring the FetchTuple time down since there will be
> > less tuples to fetch.
> >
> >
> > If the planner is already producing optimized plans, then
> > what's your proposal?
> >
> >
> >
> >
> >
> > Thanks
> >
> > On Wed, 2015-06-03 at 09:45 +0500, Abbas Butt wrote:
> > >
> > >
> > > On Wed, Jun 3, 2015 at 4:11 AM, Manikandan
> > Soundarapandian
> > > <ma...@vt...> wrote:
> > > Hi,
> > >
> > >
> > > I am a graduate student working on my
> > research in parallel
> > > databases. I would like to know how the
> > postgres-xc
> > > coordinator works. I understand that the
> > datanodes run the
> > > query in parallel and the results are
> > collected by the
> > > coordinator which runs any more
> > computation that is required
> > > or just provides the output to the client
> > that requested the
> > > query. I would like to know whether the
> > coordinator does this
> > > data collection from datanodes in a
> > sequential fashion?
> > >
> > >
> > > The coordinator uses multiplexed IO using select
> > on all fds of
> > > datanodes. For more details please see
> > pgxc_node_receive function in
> > > pgxcnode.c. The loop for reading data on all set
> > fds is sequential,
> > > but the coordinator does not wait for data from
> > the datanode to which
> > > the coordinator had sent the query first.
> > >
> > > For example, lets consider we want to run
> > the query on table
> > > table_x which is hash distributed among 10
> > datanodes,
> > > select count(*) from table_x;
> > > Each datanode will run the query and give
> > their local counts
> > > and the coordinator has to collect the
> > individual counts and
> > > come up with the final count before
> > sending the output. Is the
> > > data collection process at the coordinator
> > done in a
> > > sequential fashion? I am actually looking
> > to introduce some
> > > kind of parallelism in this data
> > collection if it is
> > > sequential and do performance studies.
> > Please clarify.
> > >
> > >
> > > To improve performance of any system, first study
> > the bottleneck, and
> > > target to widen that. Have you done any study of
> > Postgres-XC to find
> > > where the performance bottleneck is?
> > >
> > >
> > >
> > > --
> > > Thanks
> > > Mani
> > > Department of Computer Science
> > > Virginia Tech
> > >
> > >
> > ------------------------------------------------------------------------------
> > >
> > >
> > _______________________________________________
> > > Postgres-xc-developers mailing list
> > >
> > Pos...@li...
> > >
> > https://lists.sourceforge.net/lists/listinfo/postgres-xc-developers
> > >
> > >
> > >
> > >
> > >
> > > --
> > > --
> > > Abbas
> > > Architect
> > >
> > >
> > > Ph: 92.334.5100153
> > >
> > > Skype ID: gabbasb
> > >
> > > www.enterprisedb.com
> > >
> > > Follow us on Twitter
> > > @EnterpriseDB
> > >
> > > Visit EnterpriseDB for tutorials, webinars,
> > whitepapers and more
> > >
> >
> >
> >
> >
> >
> >
> >
> > --
> > --
> > Abbas
> > Architect
> >
> >
> > Ph: 92.334.5100153
> >
> > Skype ID: gabbasb
> >
> > www.enterprisedb.com
> >
> > Follow us on Twitter
> > @EnterpriseDB
> >
> > Visit EnterpriseDB for tutorials, webinars, whitepapers and
> > more
> >
>
>
>
>
>
>
>
> --
>
> --
> Abbas
>
> Architect
>
>
> Ph: 92.334.5100153
>
> Skype ID: gabbasb
>
>
> www.enterprisedb.com
>
> Follow us on Twitter
> @EnterpriseDB
>
> Visit EnterpriseDB for tutorials, webinars, whitepapers and more
>
|