materialize()

Записывает значение табличного выражения на время выполнения запроса, чтобы запрос на него можно было ссылаться несколько раз без пересчета.

Синтаксис

materialize(expression)

Дополнительные сведения о соглашениях о синтаксисе.

Параметры

Имя Тип Обязательно Описание
expression string ✔️ Табличное выражение, вычисляемое и кэшированное во время выполнения запроса.

Комментарии

Функция materialize() полезна в следующих сценариях:

  • Для ускорения запросов, выполняющих сложные вычисления, результаты которых используются в запросе несколько раз.
  • Вычисление табличного выражения только один раз и его многократное использование в запросе. Обычно это требуется, если табличное выражение является недетерминированным. Например, если выражение использует rand() функции или dcount() .

Примечание

Размер кэша Materialize ограничен в 5 ГБ. Это ограничение равно каждому узлу кластера и является взаимным для всех запросов, выполняющихся одновременно. Если запрос использует materialize() и кэш не может содержать больше данных, запрос прервется с ошибкой.

Совет

Другим способом выполнения материализации табличного выражения является использование hint.materialized флага как оператора и оператора секционирования. Все они используют один кэш материализации.

Совет

  • Отправка всех возможных операторов, которые сокращают материализованный набор данных и сохраняют семантику запроса. Например, используйте общие фильтры поверх того же материализованного выражения.
  • Используйте материализацию с соединением или объединением, если их операнды имеют взаимные вложенные запросы, которые можно выполнить один раз. Например, вилки соединения или объединения. См . пример использования оператора join.
  • Materialize можно использовать в инструкциях let только в том случае, если вы присвоите кэшированному результату имя. См . пример использования операторов let.

Примеры повышения производительности запросов

В следующем примере показано, как materialize() можно использовать для повышения производительности запроса. Выражение _detailed_data определяется с помощью materialize() функции и поэтому вычисляется только один раз.

let _detailed_data = materialize(StormEvents | summarize Events=count() by State, EventType);
_detailed_data
| summarize TotalStateEvents=sum(Events) by State
| join (_detailed_data) on State
| extend EventPercentage = Events*100.0 / TotalStateEvents
| project State, EventType, EventPercentage, Events
| top 10 by EventPercentage

Выходные данные

Состояние EventType EventPercentage События
ГАВАЙИ УОТЕРС Торнадо 100 2
ОЗЕРО ОНТАРИО Морской грозовой ветер 100 8
ЗАЛИВ АЛЯСКИ Торнадо 100 4
АТЛАНТИЧЕСКИЙ СЕВЕР Морской грозовой ветер 95.2127659574468 179
LAKE ERIE Морской грозовой ветер 92.5925925925926 25
E PACIFIC Торнадо 90 9
ОЗЕРО МИЧИГАН Морской грозовой ветер 85.1648351648352 155
ОЗЕРО ХУРОН Морской грозовой ветер 79.3650793650794 50
МЕКСИКАНСКИЙ ЗАЛИВ Морской грозовой ветер 71.7504332755633 414
ГАВАЙИ Высокий серф 70.0218818380744 320

В следующем примере создается набор случайных чисел и выполняется вычисление:

  • Сколько разных значений в наборе (Dcount)
  • Три первых значения в наборе
  • Сумма всех этих значений в наборе

Эту операцию можно выполнить с помощью пакетов и материализовать:

let randomSet = 
    materialize(
        range x from 1 to 3000000 step 1
        | project value = rand(10000000));
randomSet | summarize Dcount=dcount(value);
randomSet | top 3 by value;
randomSet | summarize Sum=sum(value)

Результирующий набор 1:

Dcount
2578351

Результирующий набор 2:

значение
9999998
9999998
9999997

Результирующий набор 3:

SUM
15002960543563

Примеры использования materialize()

Совет

Материализуйте столбец во время приема, если большинство запросов приводят к извлечению полей из динамических объектов в миллионах строк.

Чтобы использовать инструкцию let со значением, которое используется несколько раз, используйте функцию materialize(). Попробуйте отправить все возможные операторы, которые позволят уменьшить материализованный набор данных и сохранить семантику запроса. Например, используйте фильтры или проецируете только обязательные столбцы.

    let materializedData = materialize(Table
    | where Timestamp > ago(1d));
    union (materializedData
    | where Text !has "somestring"
    | summarize dcount(Resource1)), (materializedData
    | where Text !has "somestring"
    | summarize dcount(Resource2))

Фильтр в Text является взаимным и может быть отправлен в выражение materialize. Запросу требуются только столбцы Timestamp, Text, Resource1и Resource2. Проецируемые эти столбцы внутри материализованного выражения.

    let materializedData = materialize(Table
    | where Timestamp > ago(1d)
    | where Text !has "somestring"
    | project Timestamp, Resource1, Resource2, Text);
    union (materializedData
    | summarize dcount(Resource1)), (materializedData
    | summarize dcount(Resource2))

Если фильтры не идентичны, как показано в следующем запросе:

    let materializedData = materialize(Table
    | where Timestamp > ago(1d));
    union (materializedData
    | where Text has "String1"
    | summarize dcount(Resource1)), (materializedData
    | where Text has "String2"
    | summarize dcount(Resource2))

Если объединенный фильтр значительно уменьшает материализованный результат, объедините оба фильтра в материализованном результате с помощью логического or выражения, как показано в следующем запросе. Однако оставьте фильтры в каждой части объединения, чтобы сохранить семантику запроса.

    let materializedData = materialize(Table
    | where Timestamp > ago(1d)
    | where Text has "String1" or Text has "String2"
    | project Timestamp, Resource1, Resource2, Text);
    union (materializedData
    | where Text has "String1"
    | summarize dcount(Resource1)), (materializedData
    | where Text has "String2"
    | summarize dcount(Resource2))