Перейти к основному содержимому
Версия: 7.0

Материализации

Практически любое агрегированное свойств в платформе можно материализовать. В этом случае свойство будет храниться в базе данных постоянно и автоматически обновляться при изменении данных, от которых это свойство зависит. При этом при чтении значений такого материализованного свойства, эти значения будут читаться непосредственно из базы, как если бы свойство было первичным (а не вычисляться каждый раз). Соответственно, все первичные свойства являются материализованными по определению.

Свойство можно материализовать, тогда и только тогда, когда для него существует конечное число наборов объектов, для которых значение этого свойства не NULL (то есть операция итерации по всем его не NULL значениям будет корректной)

Хранимые значения материализованного свойства можно пересчитать — заново вычислить из определения свойства. Это нужно, когда эти значения могли разойтись с определением, например после изменения определения свойства или после прямого исправления данных.

Пересчет

Пересчет материализованного свойства сверяет сохраненные значения с его определением и записывает обратно те, что разошлись. То, как именно это делается, задают несколько рабочих параметров.

useRecalculateClassesInsteadOfInconsisentExpr (по умолчанию true) сначала пересчитывает классы таблицы, в которой хранится свойство, и только потом сверяет значения - так сверка может пользоваться обычным выражением свойства. При выключенном параметре классы не трогаются, а сверка идет по выражению, которое терпит несогласованные данные о классах, что добавляет соединений и требует больше памяти. Из двух вариантов пересчет классов грубее: он переписывает данные о классах всей таблицы. Если пересчет запрошен без классов, параметр не действует.

recalculateMaterializationsMixedSerializable (по умолчанию false) меняет то, как пересчет, идущий в собственной транзакции, удерживает уровень изоляции: расходящиеся строки сначала собираются вне транзакции, и на строгом уровне выполняется только их обратная запись. Это стоит лишней временной таблицы и второго запроса и ничего не меняет для пересчета, который администратор попросил выполнить в одной общей транзакции.

maxRecalculateTime (300000 миллисекунд) - не таймаут, по нему ничего не прерывается. Операция, занявшая больше этого времени, добавляется в отчет, который возвращает сервисное действие, - так видно медленные таблицы и свойства; 0 выводит в отчет практически каждую операцию, так как сравнение строгое.

groupByTables (по умолчанию true) группирует пересчитываемые свойства по таблице, в которой они хранятся: при многопоточном пересчете свойства одной таблицы выполняются одно за другим, а не одновременно, и поэтому не ждут блокировок друг друга. Он же обновляет - при старте сервера - статистику по колонкам, которые синхронизация схемы базы только что создала или перенесла. При выключенном параметре это обновление статистики пропускается совсем, и запросы по таким колонкам сохраняют плохие планы, пока статистика не будет пересчитана иначе, поэтому его лучше оставить включенным.

Язык

Для материализации свойства используется опция MATERIALIZED в опциях свойств. Для пересчета хранимых значений материализованного свойства используется оператор RECALCULATE.

Примеры

sum = GROUP SUM sum(OrderDetail od) BY order(od) MATERIALIZED;
date(OrderDetail od) = date(order(od)) MATERIALIZED;

// такое свойство нельзя материализовать, так как оно не NULL для бесконечного числа дат
lastDate(Customer customer, DATE date) = GROUP LAST date(Order order) IF customer(order) = customer AND date(order) < date ORDER order;