Adaptive MV Usage in ClickHouse

Scenario

Materialized views (MVs) are used in ClickHouse to save the precomputed result of time-consuming operations. When querying data, you can query the materialized views rather than the original tables, thereby quickly obtaining the query result.

Currently, MVs are not easy to use in ClickHouse. Users can create one or more MVs based on the original table data as required. Once multiple MVs are created, you need to identify which MV is used and convert the query statement of an original table to that of an MV. In this way, the querying process is inefficient and prone to errors.

The problem mentioned above is readily solved since the adoption of adaptive MVs. When querying an original table, the corresponding MV of this table will be queried, which greatly improves the usability and efficiency of ClickHouse.

Matching Rules of Adaptive MVs

To ensure that the SQL statement for querying an original table can be automatically converted to that for querying the corresponding MV, the following matching rules must be met:

For details about common matching failures of adaptive MVs, see Common Matching Failures of MVs.

Using Adaptive MVs

In the following operations, local_table is the original table and view_table is the MV created based on local_table. Change the table creation and query statements based on the site requirements.

  1. Use the ClickHouse client to connect to the default database. For details, see Using ClickHouse from Scratch.
  2. Run the following table creation statements to create the original table local_table.

    CREATE TABLE local_table
    (
    id String,
    city String,
    code String,
    value UInt32,
    create_time DateTime,
    age UInt32
    )
    ENGINE = MergeTree
    PARTITION BY toDate(create_time)
    ORDER BY (id, city, create_time);

  3. Create the MV view_table based on local_table.

    CREATE MATERIALIZED VIEW view_table
    ENGINE = AggregatingMergeTree
    PARTITION BY toDate(create_time)
    ORDER BY (id, city, create_time)
    AS SELECT
    create_time,
    id,
    city,
    uniqState(code),
    sumState(value) AS value_new,
    minState(create_time) AS first_time,
    maxState(create_time) AS last_time
    FROM local_table
    WHERE create_time >= toDateTime('2021-01-01 00:00:00')
    GROUP BY id, city, create_time;

  4. Insert data to the local_table table.

    INSERT INTO local_table values('1','zzz','code1',1,toDateTime('2021-01-02 00:00:00'), 10);
    INSERT INTO local_table values('2','kkk','code2',2,toDateTime('2020-01-01 00:00:00'), 20);
    INSERT INTO local_table values('3','ccc','code3',3,toDateTime('2022-01-01 00:00:00'), 30);

  5. Run the following command to enable the adaptive MVs.

    set adaptive_materilized_view = 1;

    If the adaptive_materilized_view parameter is set to 1, the adaptive MVs are enabled. If it is set to 0, the adaptive MVs are disabled. The default value is 0. set adaptive_materilized_view = 1; is a session-level command and needs to be reset each time the client connects to the server.

  6. Query data in the local_table table.

    SELECT sum(value)
    FROM local_table
    WHERE create_time >= toDateTime('2021-01-01 00:00:00')
    ┌─sumMerge(value_new)─┐
    │ 4 │
    └─────────────────────┘

  7. Run the explain syntax command to view the execution plan of the SQL statement in step 6. According to the query result, view_table is queried.

    EXPLAIN SYNTAX
    SELECT sum(value)
    FROM local_table
    WHERE create_time >= toDateTime('2021-01-01 00:00:00')
    ┌─explain────────────────────┐
    │ SELECT sumMerge(value_new) │
    │ FROM default.view_table    │
    └────────────────────────────┘

Common Matching Failures of MVs