Sort keys and prefix indexes
When you create a table, you can select one or more of its columns to comprise a sort key. The sort key determines the order in which the data of the table is sorted before the data is stored on disk. You can use the sort key columns as filter conditions for queries. As such, StarRocks can quickly locate the data of interest, saving it from scanning the entire table to find the data that it needs to process. This reduces search complexity and therefore accelerates queries.
Additionally, to reduce memory consumption, StarRocks supports creating a prefix index on a table. Prefix indexes are a type of spare index. StarRocks stores every 1024 rows of the table in a block, for which an index entry is generated and stored in the prefix index table. The prefix index entry for a block cannot exceed 36 bytes in length, and its content is the prefix composed of the table's sort key columns in the first row of that block. This helps StarRocks quickly locate the starting column number of the block that stores the data of that row when a search on the prefix index table is run. The prefix index of a table is 1024 times less than the table itself in size. Therefore, the entire prefix index can be cached in memory to help accelerate queries.
Principles
In the Duplicate Key table, sort key columns are defined by using the DUPLICATE KEY
keyword.
In the Aggregate table, sort key columns are defined by using the AGGREGATE KEY
keyword.
In the Unique Key table, sort key columns are defined by using the UNIQUE KEY
keyword.
Since v3.0, the primary key and sort key are decoupled in the Primary Key table. The sort key columns are defined by using the ORDER BY
keyword. The primary key columns are defined by using the PRIMARY KEY
keyword.
When you define sort key columns for a Duplicate Key table, an Aggregate table, or a Unique Key table, take note of the following points:
-
Sort key columns must be continuously defined columns, of which the first defined column must be the beginning sort key column.
-
The columns that you plan to select as sort key columns must be defined prior to the other common columns.
-
The sequence in which you list sort key columns must comply with the sequence in which you define the columns of the table.
The following examples show allowed sort key columns and unallowed sort key columns of a table that consists of four columns, which are site_id
, city_code
, user_id
, and pv
:
-
Examples of allowed sort key columns
site_id
andcity_code
site_id
,city_code
, anduser_id
-
Examples of unallowed sort key columns
city_code
andsite_id
city_code
anduser_id
site_id
,city_code
, andpv
The following sections provide examples of how to define sort key columns when you create tables of different types. These examples are suitable for StarRocks clusters that have at least three BEs.
Duplicate Key
Create a table named site_access_duplicate
. The table consists of four columns: site_id
, city_code
, user_id
, and pv
, of which site_id
and city_code
are selected as sort key columns.
The statement for creating the table is as follows:
CREATE TABLE site_access_duplicate
(
site_id INT DEFAULT '10',
city_code SMALLINT,
user_id INT,
pv BIGINT DEFAULT '0'
)
DUPLICATE KEY(site_id, city_code)
DISTRIBUTED BY HASH(site_id);
NOTICE
Since v2.5.7, StarRocks can automatically set the number of buckets (BUCKETS) when you create a table or add a partition. You no longer need to manually set the number of buckets. For detailed information, see determine the number of buckets.
Aggregate Key
Create a table named site_access_aggregate
. The table consists of four columns: site_id
, city_code
, user_id
, and pv
, of which site_id
and city_code
are selected as sort key columns.
The statement for creating the table is as follows:
CREATE TABLE site_access_aggregate
(
site_id INT DEFAULT '10',
city_code SMALLINT,
user_id BITMAP BITMAP_UNION,
pv BIGINT SUM DEFAULT '0'
)
AGGREGATE KEY(site_id, city_code)
DISTRIBUTED BY HASH(site_id);
NOTICE
For an Aggregate table, columns for which
agg_type
is not specified are key columns, and those for whichagg_type
is specified are value columns. See CREATE TABLE. In the preceding example, onlysite_id
andcity_code
are specified as sort key columns, and thereforeagg_type
must be specified foruser_id
andpv
.
Unique Key
Create a table named site_access_unique
. The table consists of four columns: site_id
, city_code
, user_id
, and pv
, of which site_id
and city_code
are selected as sort key columns.
The statement for creating the table is as follows:
CREATE TABLE site_access_unique
(
site_id INT DEFAULT '10',
city_code SMALLINT,
user_id INT,
pv BIGINT DEFAULT '0'
)
UNIQUE KEY(site_id, city_code)
DISTRIBUTED BY HASH(site_id);
Primary Key
Create a table named site_access_primary
. The table consists of four columns: site_id
, city_code
, user_id
, and pv
, of which site_id
is selected as the primary key column, site_id
and city_code
are selected as sort key columns.
The statement for creating the table is as follows:
CREATE TABLE site_access_primary
(
site_id INT DEFAULT '10',
city_code SMALLINT,
user_id INT,
pv BIGINT DEFAULT '0'
)
PRIMARY KEY(site_id)
DISTRIBUTED BY HASH(site_id)
ORDER BY(site_id,city_code);
Sorting effect
Use the preceding tables as examples. The sorting effect varies in the following three situations:
-
If your query filters on both
site_id
andcity_code
, the number of rows that StarRocks needs to scan during the query is significantly reduced:select sum(pv) from site_access_duplicate where site_id = 123 and city_code = 2;
-
If your query filters only on
site_id
, StarRocks can narrow the query range down to the rows that containsite_id
values:select sum(pv) from site_access_duplicate where site_id = 123;
-
If your query filters only on
city_code
, StarRocks needs to scan the entire table:select sum(pv) from site_access_duplicate where city_code = 2;
NOTE
In this situation, the sort key columns do not yield the expected sorting effect.
As described above, when your query filters on both site_id
and city_code
, StarRocks runs a binary search on the table to narrow the query range down to a specific location. If the table consists of a large number of rows, StarRocks runs binary searches on the site_id
and city_code
columns instead. This requires StarRocks to load the data of the two columns into memory and therefore increases memory consumption. In this case, you can use a prefix index to reduce the amount of data cached in memory, thereby accelerating your query.
Additionally, note that a large number of sort key columns also increase memory consumption. To reduce memory consumption, StarRocks imposes the following limits on the usage of prefix indexes:
-
The prefix index entry of a block must be composed of the prefix of the table's sort key columns in the first row of that block.
-
A prefix index can be created on a maximum of 3 columns.
-
A prefix index entry cannot exceed 36 bytes in length.
-
A prefix index cannot be created on columns of the FLOAT or DOUBLE data type.
-
Of all the columns on which a prefix index is created, only one column of the VARCHAR data type is allowed, and that column must be the end column for the prefix index.
-
If the end column for a prefix index is of the CHAR or VARCHAR data type, no entries in the prefix index can exceed 36 bytes.
How to select sort key columns
This section uses the site_access_duplicate
table as an example to describe how to select sort key columns.
-
We recommend that you identify the columns on which your queries frequently filter and select these columns as sort key columns.
-
If you select more than one sort key column, we recommend that you list frequently filtered columns of high discrimination levels prior to the other columns.
A column has a high discrimination level if the number of values in the column is large and continuously grows. For example, the number of cities in the
site_access_duplicate
table is fixed, which means that the number of values in thecity_code
column of the table is fixed. However, the number of values in thesite_id
column is much greater than the number of values in thecity_code
column and continuously grows. Therefore, thesite_id
column has a higher discrimination level than thecity_code
column. -
We recommend that you do not select a large number of sort key columns. A large number of sort key columns cannot help improve query performance but increase the overheads for sorting and data loading.
In summary, take note of the following points when you select sort key columns for the site_access_duplicate
table:
-
If your queries frequently filter on both
site_id
andcity_code
, we recommend that you selectsite_id
as the beginning sort key column. -
If your queries frequently filter only on
city_code
and occasionally filter on bothsite_id
andcity_code
, we recommend that you selectcity_code
as the beginning sort key column. -
If the number of times that your queries filter on both
site_id
andcity_code
is roughly equal to the number of times that your queries filter only oncity_code
, we recommend that you create a materialized view, for which the first column iscity_code
. As such, StarRocks creates a sort index on thecity_code
column of the materialized view.