Skip to main content
Question

How to evaluate segmentation expression?

  • February 27, 2019
  • 5 replies
  • 16 views

mkheir
Forum|alt.badge.img+1
  • Participating Frequently

Hello,

Is there a way to get the data segmentation accross nodes based on a column and a cluster size.

I have simulated a case where I break initial segmentation rule and need to change segmentation expression.

table I m using is named 'mytable' and have the column ID as a primary key and HASH(ID) in segmentation column clause.

My initial table (mytable) is well segmented.

dbadmin=> select node_name, projection_schema, projection_name, anchor_table_name, row_count
dbadmin-> from projection_storage
dbadmin-> where projection_schema ='test'
dbadmin->         and anchor_table_name = 'mytable'
dbadmin->         and  projection_name ='mytable_b0'
dbadmin-> order by 1;
   node_name   | projection_schema | projection_name | anchor_table_name | row_count
---------------+-------------------+-----------------+-------------------+-----------
 v_kb_node0001 | test              | mytable_b0      | mytable           |    939667
 v_kb_node0002 | test              | mytable_b0      | mytable           |    940459
 v_kb_node0003 | test              | mytable_b0      | mytable           |    940889
 v_kb_node0004 | test              | mytable_b0      | mytable           |    939362
 v_kb_node0005 | test              | mytable_b0      | mytable           |    939706
(5 rows)

After deleting data from one node (just simulating a deletion/update that break a correct segmentation)

dbadmin=> delete from test.mytable where local_node_name() = 'v_kb_node0001';
 OUTPUT
--------
 939667
(1 row)
dbadmin=> commit;
COMMIT


select DO_TM_TASK('moveout','test.mytable');
select DO_TM_TASK('mergeout','test.mytable');

now data is not present in node1:

dbadmin=> select node_name, projection_schema, projection_name, anchor_table_name, row_count
dbadmin-> from projection_storage
dbadmin-> where projection_schema ='test'
dbadmin->         and anchor_table_name = 'mytable'
dbadmin->         and  projection_name ='mytable_b0'
dbadmin-> order by 1;
   node_name   | projection_schema | projection_name | anchor_table_name | row_count
---------------+-------------------+-----------------+-------------------+-----------
 v_kb_node0001 | test              | mytable_b0      | mytable           |         0
 v_kb_node0002 | test              | mytable_b0      | mytable           |    940459
 v_kb_node0003 | test              | mytable_b0      | mytable           |    940889
 v_kb_node0004 | test              | mytable_b0      | mytable           |    939362
 v_kb_node0005 | test              | mytable_b0      | mytable           |    939706
(5 rows)

My goal is to find a query that might give the same distribution as above.
I found the below query in the forum, but it seem not to be giving the correct segmentation distribution :

dbadmin=> SELECT FLOOR(HASH(ID)/((9223372036854775807/5) + 1)) AS Node,
dbadmin->        COUNT(*) AS row_count
dbadmin->   FROM test.mytable
dbadmin-> GROUP BY 1
dbadmin-> ORDER BY 1;
 Node | row_count
------+-----------
    0 |    752296
    1 |    752671
    2 |    752863
    3 |    750851
    4 |    751735
(5 rows)

Note: I also tried exporting data (after deletion of node1 data) to a file and loading it again using COPY command, it also show that node1 data is empty, which is expected as segmentation rely on the same values.

Can you please help with a query that can allow to evaluate segmentation expressions.

Many thanks.
Mkheir.

5 replies

Vertica_Curtis
Forum|alt.badge.img+1
  • Participating Frequently
  • February 27, 2019

Not sure what you're after here. Are you wanting to see data skew? This query will do that:

select distinct lower(trim(ps.projection)) as projection
, first_value(to_char(used_bytes/1024^2, '999,999.9999')) over (w order by used_bytes asc) as min_used_MB
, first_value(to_char(used_bytes/1024^2, '999,999,999.9999')) over (w order by used_bytes desc) as max_used_MB
, to_char((first_value(used_bytes) over (w order by used_bytes asc) /
first_value(used_bytes) over (w order by used_bytes desc)-1) -1100, '99.9999%') as skew_pct
from
(select node_name, projection_id, projection_schema || '.' || projection_name as projection
, sum(used_bytes) as used_bytes
from projection_storage group by 1,2,3 ) as ps
join projections p using (projection_id)
where p.is_segmented
and ps.used_bytes > 1000000
window w as (partition by ps.projection)
order by 4 desc limit 30 ;


mkheir
Forum|alt.badge.img+1
  • Author
  • Participating Frequently
  • February 28, 2019

Hi Curtis,

Thanks for the query.

What I m looking for, is to have a way to evaluate how a column is a good candidate for segmentation.

I've found a query (see previous comment) that is not showing what Vertica does.

Regards.
Mohamed.


Jim_Knicely
Forum|alt.badge.img+2
  • Participating Frequently
  • February 28, 2019

mkheir
Forum|alt.badge.img+1
  • Author
  • Participating Frequently
  • February 28, 2019

Hi Jim,
Unfortunately no, the query from this post is not providing the distribution that Vertica apply.

Using the query from the post I get an even distribution:

dbadmin=> SELECT FLOOR(HASH(ID)/((9223372036854775807/5) + 1)) AS Node,
dbadmin->        COUNT(*) AS row_count
dbadmin->   FROM test.mytable
dbadmin-> GROUP BY 1
dbadmin-> ORDER BY 1;
 Node | row_count
------+-----------
    0 |    752296
    1 |    752671
    2 |    752863
    3 |    750851
    4 |    751735
(5 rows)

But when loading the data using HASH(ID) for segmentation (ON ALL NODES), Vertica apply different logic:

dbadmin=> select node_name, projection_schema, projection_name, anchor_table_name, row_count
dbadmin-> from projection_storage
dbadmin-> where projection_schema ='test'
dbadmin->         and anchor_table_name = 'mytable'
dbadmin->         and  projection_name ='mytable_b0'
dbadmin-> order by 1;
   node_name   | projection_schema | projection_name | anchor_table_name | row_count
---------------+-------------------+-----------------+-------------------+-----------
 v_kb_node0001 | test              | mytable_b0      | mytable           |         0
 v_kb_node0002 | test              | mytable_b0      | mytable           |    940459
 v_kb_node0003 | test              | mytable_b0      | mytable           |    940889
 v_kb_node0004 | test              | mytable_b0      | mytable           |    939362
 v_kb_node0005 | test              | mytable_b0      | mytable           |    939706
(5 rows)

Which let me think that the query from the post you referenced is not using rules that vertica apply.

Many thanks for your help.


Vertica_Curtis
Forum|alt.badge.img+1
  • Participating Frequently
  • March 20, 2019

FYI, Jack no longer works at Vertica. He was formerly at Playtika, and they became masters of this sort of stuff. Jack did a lot of this kind of stuff at Intuit - they'd created their main tax table with default segmentation, and we had to rebuild it for them. It was too large to just copy straight over, so Jack did it through Scala one node at a time using these segmentation ranges.