Got it, thanks! Look forward to this new feature!

Best,
Gabriel

On Tue, 26 Apr 2022 at 17:13, GuoLei Yi <yiguo...@gmail.com> wrote:

> @ Gabriel Lee
> >
> > 1. I think we cannot trust users completely, so we should add a
> protection
> > mechanism for global dictionary. For example, fallback to raw string
> > processing when entries in dictionary are too many.
>
>
> Yes, you are right, we cannot trust users completely. If there are too many
> strings (for example 10000 > 1024), global dict will be invalid and not
> updated any more. All queries on that table will fallback to raw string
> processing.
>
> 2. Should we consider local dictionary instead of global dictionary? In my
> > mind, global dictionary is hard to maintain in an efficient way. For
> > example,
> >
>
> We need global dict because the encoded string will be shuffled across
> among BEs. If use a local dict then raw strings on different BE will have
> different and we will also depend on global dict to optimize join operation
> and the join operation is on different columns and should depend on global
> dict.
>
> 3. Seems like that aggregate function dict is same as distinct, is it
> right?
> >
>
> Yeah.... Currently, it is a little uglily. We use a special function name
> to indicate that the scan node should read the meta column of the
> rowset.....
>
> Gabriel Lee <gabrielleeb...@gmail.com> 于2022年4月26日周二 14:54写道:
>
> > Hi Guolei,
> > I have some questions for this.
> > 1. I think we cannot trust users completely, so we should add a
> protection
> > mechanism for global dictionary. For example, fallback to raw string
> > processing when entries in dictionary are too many.
> > 2. Should we consider local dictionary instead of global dictionary? In
> my
> > mind, global dictionary is hard to maintain in an efficient way. For
> > example,
> >     2.1 we should add more synchronization mechanism for this global
> > dictionary to ensure consistency which drastically increase complexity
> >     2.2 an background worker incurs additional workloads for both FE and
> BE
> > 3. Seems like that aggregate function dict is same as distinct, is it
> > right?
> >
> > On Tue, 26 Apr 2022 at 11:04, GuoLei Yi <yiguo...@gmail.com> wrote:
> >
> > > *Issue Description:*
> > >
> > > In Doris, many dimension columns are string type with low cardinality
> > > (cardinality < 1024), such as some status codes, provinces, regions,
> > > genders, etc. During group by or join operation, it has to make a hash
> > > table in the form of strings. The efficiency is relatively low. Through
> > > performance testing, it is found that the performance is about 3 times
> > > worse than using int type. If we can convert string to int through a
> > global
> > > dictionary during a query, then the query efficiency will be greatly
> > > improved. The solution is described below.
> > >
> > > *Design:*
> > >
> > > Maintain global dictionary for every column in FE as needed, for
> example
> > it
> > > could be organized as map<(table_id,col_id), dict> in DictManager.
> > > When creating a table, set the attribute of the field to
> low_cardinality
> > to
> > > identify whether the field is a low-cardinality field. For
> > low-cardinality
> > > fields, use a global dictionary to speed up the corresponding query.
> The
> > > specific syntax is as follows:
> > >
> > > // create table
> > > create table table_name (
> > >     col1 int,
> > >     col2 string|varchar(10) low_cardinality
> > > );
> > >
> > > // alter table
> > > alter table table_name modify column col2 set low_cardinality=true
> > >
> > > At the beginning, the dict is empty, so it will not be used during
> query.
> > > FE will start a background task to obtain global dictionary information
> > > from BE for every low cardinality column, and the task is sent to BE in
> > the
> > > form of SQL, as follows:
> > >
> > > select dict(col) from table[meta]
> > >
> > > So that there will be a new aggregation method dict and new scannode in
> > BE.
> > > In the new scannode, BE reads the local dictionary of each field and
> get
> > > all dictinct strings. dict is an aggregation function that deduplicates
> > and
> > > merges the dictionaries of multiple BEs and tablets. The final result
> is
> > > saved in FE's DictManager.
> > >
> > > During query, FE puts the global dictionary information into the
> Fragment
> > > structure and sends it to each BE. The structure is as follows:
> > >
> > > struct TStringColumnDict {
> > > list<int16> id,    // the offset or id of the string
> > > list<string> value    // the string value
> > > }
> > > struct TColumnDict {
> > > TStringColumnDict xxx,
> > > TDateColumnDict xxx,
> > > ....
> > > }
> > > struct TGlobalDict {
> > > map<id, TColumnDict> columnDicts // map from column id to column dict
> > > }
> > > struct TExecPlanFragmentParams {
> > > ...
> > > TGlobalDict globalDict
> > > }
> > >
> > > The OlapScanNode will encodes the string data according to the value
> and
> > ID
> > > of each string in the dict, and the subsequent calculations (such as
> > group
> > > by) are operated according to int, and at the final result sink node,
> the
> > > result is decode into the corresponding string.
> > >
> > >
> > > *Maintain GlobalDict Changes*
> > >
> > > During process of loading, user will import new strings that are not in
> > the
> > > GlobalDict, so this requires an update mechanism for the global
> > dictionary.
> > > Stream load is actually a query, so it will also generate a fragment,
> and
> > > according to the task description of our query, there is a global dict
> in
> > > the fragment. In TabletSink, each value of the column of low
> cardinality
> > > should be evaluated with ColumnDict, if find a new string, the
> > coordinator
> > > need to inform FE that the dict of this column is invalid.
> Specifically,
> > we
> > > need to make some modifications in LoadTxnCommitRequest and add a field
> > to
> > > indicate which columns are invalid.
> > >
> > > struct TLoadTxnCommitRequest {
> > > ...
> > > list<int> invalid_col_ids
> > > }
> > >
> > > Invalid col ids should be persisted to the transaction state. Once the
> > > transaction is published, we will delete the dict from the dict
> manager.
> > In
> > > this way, the query will not use this dictionary optimization in the
> > > future. At the same time, FE generates a task to get the latest Dict.
> > When
> > > the latest Dict is obtained, the query can be optimized using Dict
> again.
> > >
> > >
> > >
> > >
> > >
> > > --
> > > Best Regards
> > >
> > > Tel:134-3991-0228
> > > Email:yiguo...@gmail.com
> > >
> >
>
>
> --
> 祝您心情愉快
>
> 衣国垒
> Tsing Hua University
> Tel:134-3991-0228
> Email:yiguo...@gmail.com
>

Reply via email to