Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Как выявить запросы, использующие materialized view, в ClickHouse


Вопрос

Как вывести все запросы, связанные с materialized view, за последние 60 минут?

Ответ

Этот запрос покажет все запросы, направленные в materialized view, при условии, что:

  • мы можем использовать поле create_table_query в таблице system.tables, чтобы определить, какие таблицы являются явными получателями MV (TO);
  • мы можем проследить, какие таблицы являются неявными получателями MV (используя uuid и соглашение об именовании .inner_id.<uuid>);

Мы также можем настроить, на какую глубину по времени выполнять поиск, изменив значение (60 m по умолчанию) в исходном CTE запроса

WITH(60) -- по умолчанию 60 мин
AS timeRange,
(
    --подготовить имена возможных неявных скрытых целевых таблиц MV для *любой* таблицы с NON NULL uuid
    SELECT groupArray(
            concat('default.`.inner_id.', toString(uuid), '`')
        )
    FROM clusterAllReplicas(default, system.tables)
    WHERE notEmpty(uuid)
) AS MV_implicit_possible_hidden_target_tables_names_array,
(
    --получает имя MV и целевые таблицы (если указано TO)
    --TODO похоже, extract возвращает только первую capturing group :( заменить на regexpExtract, когда станет доступно
    SELECT arrayFilter(
            x->x != '',
            --удалить пустые совпадения
            groupArray(
                extract(
                    create_table_query,
                    '^CREATE MATERIALIZED VIEW\s(\w+\.\w+)\s(?:TO\s(\S+))?'
                )
            )
        )
    FROM clusterAllReplicas(default, system.tables)
    WHERE engine = 'MaterializedView'
) AS MV_explicit_target_tables_names_array
SELECT event_time,
    query,
    tables as "MVs tables"
FROM clusterAllReplicas(default, system.query_log)
WHERE (
        -- только SELECT за последние 60 мин
        event_time > now() - toIntervalMinute(timeRange)
        AND startsWith(query, 'SELECT')
    ) -- проверить, что запрос обращается к неявным именам целевых таблиц MV
    AND (
        hasAny(
            tables,
            MV_implicit_possible_hidden_target_tables_names_array
        )
        OR -- проверить, что запрос обращается к явной целевой таблице MV
        hasAny(tables, MV_explicit_target_tables_names_array)
    )
ORDER BY event_time DESC;

ожидаемый результат:

| event_time          | query                                                                                          | MVs tables                                                            |
| ------------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| 2023-02-23 08:14:14 | SELECT     rand(),* FROM     default.sum_of_volumes,     default.big_changes,     system.users | ["default.big_changes_mv","default.sum_of_volumes_mv","system.users"] |
| 2023-02-23 08:04:47 | SELECT     price,* FROM     default.sum_of_volumes,     default.big_changes                    | ["default.big_changes_mv","default.sum_of_volumes_mv"]                |

В этом примере указанные выше default.big_changes_mv и default.sum_of_volumes_mv оба являются materialized view.

Navigation