Многомерные вычисления и построение кубов вMicrosoft SQL

advertisement
Обучающие игры для любознательных аналитиков младшего и среднего возраста 
Модель вычислений
Архитектура выполнения многомерного запроса
Анализ производительности и методы оптимизации
Перед нами
фрагмент
структуры
модельной БД
AdventureWorks
«Боевые» БД из
реального мира
выглядят,
очевидно, еще
сложнее
Задачи, для
которых
выстраивалась
схема OLTP, - это
учет и
накопление
данных
Удобно ли проводить анализ на основе такой структуры?
Под словом «анализ» здесь будем понимать
исследование отображений n-мерного дискретного
множества в область вещественных чисел F(Dn) -> Rm
n-мерного в том плане, что оно распадается на произведение n
независимых дискретных множеств: Dn = D1 x … x Dn
Например, Продажи в деньгах = F(География, Товары)
Продажи
Товары
География
Под продажами может пониматься не только денежное, но и
натуральное представление. Тогда будет две поверхности и
отображение в R2.
Практически никакие события реального мира не
описываются аналитически
Аналитическая зависимость – всего лишь удобная
степень приближения
Для их описания используется табличный метод
Хлеб
Молоко
Пиво
Вобла
Памперсы
Сиэтл
Редмонд
Лос-Анджелес
Сан-Франциско
Сан-Диего
15
35
55
75
80
65
105
135
155
190
105
170
215
240
245
65
105
135
155
190
15
35
55
75
80
Аналогично, когда измерений > 2, например
Время
100
100
100
100
222
75
34
48
151
123
100
100
100
100
100 100
100
100
100
100
134
87
95
83
16
60
100
100
100
100
100
96
89
77
12
55
100
100
100
100
100 100
100
100
100
100
99
126
88
66
42
98
100
100
100
100
100
133
80
65
31
94 100
100
100
100
100
7 106
100
100
100
100
50
52
68
24
92
100
100
100
100
100
43
44
76
15
84
100
100
100
100
100 100
100
100
100 201
100
51
14
64
101
59
100
100
100
100
100
32
70
111
15
226
33
100
100
100
100
104
75
155
240
155
75
80
190
245
190
80
География
Товары
Внутри каждой ячейки сидят продажи, а также все остальные
численные показатели (Rm)
На каждом Di определена унарная операция «родитель»,
возвращающая множество родительских элементов для каждого
элемента множества
P(Сан-Франциско) = Калифорния, Р(17/10/2007) = 10/2007
Она задает над Di так называемую иерархию
Таких операций может несколько, тогда говорят, что над
измерением задано несколько иерархий
Р1(17/10/2007) = 10/2007, Р2(17/10/2007) = 3-я неделя октября 2007 г.
На основе этой операции определяются обратная операция
«ребенок», операция «брат» и др.
Реб(X) = {Y}, если Р({Y}) = X; Б(X) = Y, если P(X) = P(Y)
Узлами иерархии называются те элементы Х, для которых Реб(Х) ≠
0
Остальные элементы называются листьями дерева иерархии
Как правило, отображение F(Dn) -> Rm задано для листьев Di
Заданы правила расчета Rm в узлах на основе подчиненных элементов
Измерения Di = таблицы-справочники (или совокупности таблиц)
Иерархии = PK - FK отношения
Отображение F(Dn) -> Rm = таблица фактов
Rm
Декартово
F(Dn) -> Rm
произведение Di
Например
Тем не менее далее в докладе
по соображениям удобства
визуализации в дальнейшем
будем использовать сводную
таблицу
География Товары
...
...
Редмонд
Редмонд
Редмонд
Редмонд
Редмонд
Редмонд
Редмонд
Редмонд
Редмонд
Редмонд
Редмонд
...
Хлеб
Хлеб
Хлеб
Молоко
Молоко
Молоко
Пиво
Пиво
Пиво
Вобла
Вобла
...
Время Выручка Объем
...
...
...
...
Январь
24
...
Февраль
27
...
Март
21
...
Январь
33
...
Февраль
39
...
Март
42
...
Январь
100
...
Февраль
100
...
Март
100
...
Январь
100
...
Февраль
100
...
...
...
Key Store – хранение ключей
атрибута в связке с уникальным
идентификатором DataID
Служебный идентфикатор
однозначно идентифи
всех местах
возрастает
AS,
цирует атрибут члена во
хранения, монотонно
Property store – хранятся все св-ва атрибута: имена, трансляции, ... по его DataID
Также физически упорядочено по DataID
Хэш-таблицы – материализуются на диск для ускорения выборки атрибутов при
выполнении запросов и процессинге
Хэши создаются только для двух св-в атрибута: ключа и имени
Relationship store – как следует из названия, хранит взаимоотношения атрибута с
другими атрибутами
Пример: черный спортивный шлем размера L, атрибуты: Продукт = спортивный шлем, Цвет = черный,
размера L
Запись в таблице вида 1001, 25, 5, где числа - DataID соотв.значений атрибутов
Bitmap Indexes – 1, если данный DataID существует на данной странице
Создание при процессинге; может занять время, если DataIDов много
Не создавать – выставить AttributeHierarchyOptimizedState в Not Optimized
Set Store – воспроизодит путь к
каждому члену от верхнего уровня
до текущего
All -> Bikes -> Mountain Bikes -> Mountain
Bike 500 представляется в виде 1,2,5,6,
где числа - DataIDы соответствующих
членов на разных уровнях иерархии
Structure Store – для каждого члена уровня содержит
DataIDы родителя и первого ребенка, а также общее
число детей
Записи физически упорядочены внутри уровня в соответствии
с установками OrderBy атрибута, образующего данный уровень
иерархии
Материализуются только натуральные иерархии
По партициям
Каждая партиция содержит две категории данных: детальные и
агрегаты
В случае MOLAP структуры под их хранение идентичны
Разбиты по сегментам, каждый сегмент из 256 страниц по 256
записей в каждом
В каждой записи содержатся значения всех мер из группы + DataID
гранулярных атрибутов каждого измерения
Хранятся только только записи, присутствующие в реляционной
таблице фактов, а не «тупое» произведение измерений
Проверяется, можно
ли удовлетворить
запрос из кэша
Storage Engine
Самый быстрый, т.к.
кэш всегда живет в
памяти
Можно ли
удовлетворить его из
агрегатов
Напоминание: агрегаты
рассчитываются на
этапе процессинга и
персистятся
SE не требует точного совпадения, т.к. может агрегировать на
лету более детальные агрегации
Напр., он в курсе устройства измерений и знает, что Q1 = Янв + Фев
+ Март
Если ничего из этого не удается, лезет в факты
Должен пробежать партицию, чтобы достать из нее нужные записи
Несмотря на применение bitmap-индексов, кластеризации и др.
методик внутренней оптимизации, если партиция велика, это будет
происходить медленно
Имеет смысл разделить данные на партиции так, чтобы их обработка
могла идти в параллели
SE достаточно «сообразителен», чтобы по DataID членов в
запросе отсечь ненужные партиции – см. позапредыдущий слайд
Часто можно слышать вопрос: как из частных агрегатов внутри партиций
AS получает общий агрегат в случае неаддитивной меры
Необходимо представлять себе, как устроены агрегаты Analysis Services
В качестве инструмента возьмем Aggregation Manager в составе примеров
к SP2
Дается в виде исходников на C#
Предположим для простоты, что в куб входят всего три измерения:
Customer, Product, OrderDate
Порядок существенен, в общем случае его можно видеть в редакторе
куба, закладка Cube Structure, фрейм Dimensions
Порядок атрибутов внутри каждого измерения в общем случае можно
видеть, сгенерив XML-код измерения, в элементе <Attributes>
Предположим, что в измерения входят следующие атрибуты
Customer: CustomerID, City, Region, State/Province
Product: ProductKey, Color, SubCategory, Category
OrderDate: Date, Month, Quarter, Year
Тогда агрегат по имени (0000, 0001, 0001) означает:
Битовые вектора – измерения в том порядке, как они входят в куб
Биты соответствуют атрибутам каждого измерения
Бит установлен = атрибут участвует в агрегате, бит снят = атрибут
входит туда как (All)
•
Т.е. атрибут вида (0000, 0001, 0001) – это примерно следующая таблица
Агрегаты
Category
Year
Sales
Amount
Order
Quantity
...
...
...
Bikes
Bikes
Bikes
Accessories
Accessories
Accessories
Components
Components
Components
Clothing
Clothing
2005
2006
2007
2005
2006
2007
2005
2006
2007
2005
2006
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
Остальные атрибуты входят в нее как (All)
Или Default Member
460
380
540
44
21
49
92
77
98
235
212
...
Пусть в кач-ве неаддитивной меры выступает кол-во уникальных
клиентов
Т.е. используется DISTINCT COUNT по CustomerID
Это будет означать декартово произведение предыдущей агрегатной
таблицы на столбец CustomerID
Отсюда, в Measure Group допускается только одна неаддитивная мера,
иначе сильный overhead
Партиционировать лучше по CustomerID, тогда можно суммировать
результаты партиций
Если партиционировать не по DISTINCT COUNT-атрибуту, потребуется
делать UNION агрегатных таблиц с партиций
Полуаддитивные меры типа AverageOfChildren, FirstChild, LastChild,
FirstNonEmpty, ...
Также требуют включения в агрегаты гранулярного атрибута
Пример: сумма нарастающим итогом, итог за период – последний день
периода
Если существует агрегатная таблица, в которую входит поле «День», запросы
будут отрабатывать быстрее
All
All
Q1
Jan
Feb
Mar
Q2
Apr
May
Jun
Q3
Jul
Aug
Sep
Q4
Oct
Nov
Dec
WA
Seattle
Redmond
CA
Los
Angeles
San
Francisco
San Diego
All
WA
Seattle
Redmond
CA
Los
Angeles
San
Francisco
San Diego
All
Q1
Jan
12
43
10
-
83
Feb
32
-
25
32
75
Mar
-
23
18
-
14
Apr
23
-
9
23
-
May
19
54
19
19
24
Jun
23
59
-
23
65
Jul
-
12
-
-
12
Aug
-
34
-
-
8
Sep
11
65
11
17
65
Oct
21
3
21
-
88
Nov
23
-
23
23
31
Dec
12
6
12
12
-
Q2
Q3
Q4
Синтаксис: Calculate [<subcube>];
В случае, если подкуб не задан, подразумевается текущий
подкуб
В начале выполнения скрипта текущий подкуб равен всему кубу
Не оказывает влияния на вычисляемые члены
Заполняет каждую ячейку подкуба агрегированными
данными с листьев
Без CALCULATE и определенных пользователем
формул куб будет содержать только листовые
фактовые данные
Дизайнер расчетов вставляет CALCULATE по
умолчанию в качестве первой команды скрипта
All
All
WA
Seattle
Redmond
Los
Angeles
CA
San
Francisco
San Diego
1237
475
176
299
762
148
149
465
367
110
44
66
257
53
32
172
Jan
148
55
12
43
93
10
-
83
Feb
164
32
32
-
132
25
32
75
Mar
55
23
-
23
32
18
-
14
360
178
65
113
182
28
65
89
Apr
55
23
23
-
32
9
23
-
May
135
73
19
54
62
19
19
24
Jun
170
82
23
59
88
-
23
65
235
122
11
111
113
11
17
85
Jul
24
12
-
12
12
-
-
12
Aug
42
34
-
34
8
-
-
8
Sep
169
76
11
65
93
11
17
65
275
65
56
9
210
56
35
119
Oct
133
24
21
3
109
21
-
88
Nov
100
23
23
-
77
23
23
31
Dec
42
18
12
6
24
12
12
-
Q1
Q2
Q3
Q4
Cинтаксис:
Scope(<subcube>);
<assignment>;
…
End Scope;
Направляет последующие вычисления в определенную
область куба, т.е. в подкуб
Если scope не задан, по умолчанию считается весь куб
Scope + assignment заменяет собой понятие
вычисляемых ячеек
Может быть несколько вложенных
Такое не представлялось возможным в вычисляемых ячейках
SQL Server 2000
Родительский scope при этом наследуется
Scope( Customers.Country.USA );
Scope( Customers.State.OR );
Scope( Customers.Gender.Male );
<Сейчас scope = USA, OR, Male>
this = 1000;
End Scope;
End Scope;
End Scope;
Иерархия родительского scope может быть переписана
Scope( Customers.Country.USA );
Scope( Customers.State.OR );
Scope( Customers.Gender.WA );
< Сейчас scope = USA, WA>
this = 1000;
End Scope;
<Сейчас scope = USA, OR>
this = 2000;
End Scope;
End Scope;
All
All
WA
Seattle
Redmond
Los
Angeles
CA
San
Francisco
San Diego
1237
475
176
299
762
148
149
465
367
110
44
66
257
53
32
172
Jan
148
55
12
43
93
10
-
83
Feb
164
32
32
-
132
25
32
75
Mar
55
23
-
23
32
18
-
14
360
178
65
113
182
28
65
89
Apr
55
23
23
-
32
9
23
-
May
135
73
19
54
62
19
19
24
Jun
170
82
23
59
88
-
23
65
Q1
Q2
Q3
235
Jul
24
Aug
42
Sep
169
Q4
275
SCOPE (CA)
...
END SCOPE
122
11
111
113
11
17
85
12
-
12
12
-
-
12
34
-
34
8
-
-
8
76
11
65
93
11
17
65
65
56
9
210
56
35
119
Oct
133
24
21
3
109
21
-
88
Nov
100
23
23
-
77
23
23
31
Dec
42
18
12
6
24
12
12
-
All
All
WA
Seattle
Redmond
Los
Angeles
CA
San
Francisco
San Diego
1237
475
176
299
762
148
149
465
367
110
44
66
257
53
32
172
Jan
148
55
12
43
93
10
-
83
Feb
164
32
32
-
132
25
32
75
Mar
55
23
-
23
32
18
-
14
360
178
65
113
1780
28
65
89
Apr
55
23
23
-
32
9
23
-
May
135
73
19
54
62
19
19
24
Jun
170
82
23
59
88
-
23
65
235
122
11
111
113
11
17
85
Q1
Q2
Q3
SCOPE (CA)
Q2 = [WA] * 10
END SCOPE
Jul
24
12
-
12
12
-
-
12
Aug
42
34
-
34
8
-
-
8
Sep
169
76
11
65
93
11
17
65
275
65
56
9
210
56
35
119
Oct
133
24
21
3
109
21
-
88
Nov
100
23
23
-
77
23
23
31
Dec
42
18
12
6
24
12
12
-
Q4
Централизованный репозиторий вычислений
Много легче визуализировать зависимости
Единое представление упрощает поддержку
Вычисления над измерениями остаются в Dimension Store
Унарные операторы
Custom member formulas
Процедурная модель выполнения
Команды выполняются в порядке определения
При необходимости автоматическм создается новый Calculation
Pass
Solve Order выбывает за ненадобностью – определяется
порядком скриптов
MDX-скрипт
SCOPE + Assignment
Устанавливает/обновляет значения или свойства ячеек
К свойствам ячеек относятся: format, font, fore color, back color, …
Calculated member
Новый член в иерархии = новые ячейки в пространстве куба
Вычисление значений ячеек аналогично assignment
Named set
Просто именованный набор ячеек
Не влияет ни на пространство куба, ни на значения ячеек
Прочие
Custom rollups, unary operators
KPIs
Клиентское приложение может добавлять вычисления
после MDX-скрипта
Обычно вычисляемые члены или именованные множества
Уровня сессии или запроса (предикат WITH)
MDX-скрипт имеет глобальный scope
Для каждого из 3-х масштабов поддерживаются свои кэши
Модель вычислений
Архитектура выполнения многомерного запроса
Анализ производительности и методы оптимизации
Парсинг
Наполнение осей
Вычисление значений ячеек
Сериализация результирующего множества
Рассмотрим запрос
WITH MEMBER Measures.ContributionToParent AS
„measures.Sales/(measures.Sales, Product.Currentmember.parent)‟
SELECT
Product.[Product Family].members ON COLUMNS,
Customer.Country.members
ON ROWS
FROM Sales
WHERE Measures.ContributionToParent
Клиентское приложение
MDX-запрос
Парсер
Наполнение осей
Formula Engine
Analysis Services
Drink
Food
Non-Consumable
Canada
Mexico
USA
WITH MEMBER Measures.ContributionToParent AS
„measures.Sales/(measures.Sales, Product.Currentmember.parent)‟
SELECT
Product.[Product Family].members ON COLUMNS,
Customer.Country.members
ON ROWS
FROM Sales
WHERE Measures.ContributionToParent
Клиентское приложение
MDX-запрос
Парсер
Наполнение осей
Вычисление ячеек
Операции над подкубами
Calculation Engine
s
Кэши FE
s
Кэши SE
Formula Engine
SE Evaluation Engine
Partition Data
Query
Storage
Engine
Analysis Services
Drink
Food
Non-Consumable
Canada
(null)
(null)
(null)
Mexico
(null)
(null)
(null)
USA
9.22%
71.95%
18.83%
Клиентское приложение
Сериализация результатов
MDX-запрос
Парсер
Наполнение осей
Вычисление ячеек
Операции над подкубами
Calculation Engine
s
Кэши FE
s
Кэши SE
Formula Engine
SE Evaluation Engine
Partition
Data Query
Storage
Engine
Analysis Services
Measures.ContributionToParent
Canada
Drink
(null)
Mexico
(null)
USA
9.22%
Food
(null)
Non-Consumable
(null)
(null)
(null)
71.95%
18.83%
measures.[Unit Sales]
=
(Measures.Sales, Product.Currentmember.Parent)
Drink
Food
Non-Consumable
Canada
(null)
(null)
(null)
Mexico
(null)
(null)
(null)
USA
$ 24,597.00 $ 191,940.00 $
50,236.00
All Products
/
Canada
(null)
Mexico
(null)
USA
$ 266,773.00
Одинаковый план: навигация, вычисления – повторяется для
каждой ячейки
Вычисление null’ов в то время, как мы заранее знаем, что там
будет null
В основе, в основном, две простые идеи
Вычислять не-NULLовые ячейки
Выполнять навигацию (.РrevМember, .Рarent, ...) один раз для блока вместо для
каждой ячейки
WITH MEMBER Measures.ContributionToParent AS
„measures.Sales/(measures.Sales, Product.Currentmember.parent)‟
SELECT
Product.[Product Family].members ON COLUMNS,
Customer.Country.members
ON ROWS
FROM Sales
WHERE Measures.ContributionToParent
Например, известно, что
Можно не вычислять дальше a/b, если a = null
Родитель всех Product.[Product Family].* один - [Product].[All], это
константа
Нет нужды навигировать всякий раз к этой ячейке для каждого члена в
Product.[Product Family].members
Также известно, что SE хранит (и возвращает) только непустые
данные
Обычно пространство куба достаточно разрежено
Значения существуют лишь для незначительной доли всевозможных
комбинаций ключей измерений
Drink
Food
Non-Consumable
Canada
(null)
(null)
(null)
Mexico
(null)
(null)
(null)
USA
9.22%
71.95%
18.83%
3) …а все остальное есть NULL
по определению
Country
Product
Measure
Value
USA
Drink
Contribution to Parent
9.22%
USA
Food
Contribution to Parent
71.95%
USA
Non-Consumable
Contribution to Parent
18.83%
Country Product
Measure Value
Country Product
USA
Drink
Sales
$24,597.00
USA
USA
Food
Sales
$191,940.00
USA
NonConsumable Sales
2) Выполнить над ними
вычисления (3 вместо 9)
Measure
All Products Sales
Value
$266,773.00
$50,236.00
1) Получить значения от Storage Engine. Они заведомо NOT NULL
Основные арифметические операторы: *, /, +, Основные логические операторы: <, >, <=, >=, <>, =
Основные унарные операторы: +, -, ~, веса
Статические члены: напр., [Customers].[Seattle]
Статические кортежи: напр., ([Customers].[Seattle], [Time].[2007])
Основные агрегатные функции (Sum, Min, Max, Aggregate) над:
Статическими множествами: напр., Sum({USA, Canada}, Measures.Sales)
Множествами из ф-ций .Members, PeriodsToDate, YTD/QTD/MTD, Crossjoin, Cousin,
CurrentMember, оператора диапазона (“:”) над статическими множествами
Полуаддитивные меры
Measures.CurrentMember
CurrentMember пока не прокатывает для других измерений
IIF(cond, expr, NULL)
IsEmpty
Константными скалярами: напр., NULL, “строка”, 5, 3.14
Модель вычислений
Архитектура выполнения многомерного запроса
Анализ производительности и методы оптимизации
Время выполнения запроса = время FE + время SE
Следовательно, если вы недовольны временем выполнения, для
начала нужно понять, кто съедает время: Formula Engine или
Storage Engine, потому что подход к ним нужен разный
Formula Еngine: однопоточный, сильно грузит CPU, сравнительно мало
– диск
Storage Еngine: все наоборот. Хотя CPU иногда тоже напрягает
Первый вывод на тему «Кто виноват?» делается из Perfmon или
Task Manager
Второй вывод делается в профайлере, где показывается полное
время запроса
Время на SE есть общая длительность всех событий Query Subcube
Для чистоты эксперимента используется XMLA-команда
<ClearCache>
Если вы не уверены, довольны вы временем выполнения или нет,
значит, довольны
Здоровый запрос к SE
Видно как событие Query Subcube с большим Duration
Чаще всего объясняется идущим следом событием Reading data from
partition
Что означает, что он полез в детальные факты по причине отсутствия
необходимых агрегатов
Инструменты для определения и создания необходимых агрегатов:
Usage-Based Optimization Wizard, профайлер, Agg Manager
Попал
Промазал
Если выстроить необходимые агрегаты не удается, продумайте
политику эффективного партиционирования (см., напр., слайды про
неаддитивные меры), чтобы облегчить ему процесс скана
Туча мелких запросов к SE
Видны как многочисленные события Query Subcube с незначительным
Duration
Чаще всего объясняется непрогретым кэшем SE
Используйте CREATE CACHE, чтобы предвыбрать данные в кэш
Напрягается FE
Видно по 100%-й загрузке одного процессора
По возможности переписать вычисления, чтобы использовать блоки
вместо поячеечных расчетов (см. выше)
Использовать методы оптимизации запросов (см. далее)
В AS понятие пустой ячейки не тождественно NULL
Пустой считается та, которая отсутствует в нижележащей таблице фактов, либо ее кортеж составляет
невозможную в данном кубе комбинацию
При процессинге NULL в мере интерпретируется как 0, если в св-вах меры не стоит NullProcessing = Preserve
Напр., скидка NULL – это 0 или не считать такого клиента в DISTINCT COUNT?
В вычислениях тоже: 1 + NULL = 1, а не NULL
Большинство клиентов (Excel, ProClarity, ...) по умолчанию отображают непустые
результаты, исключая члены без данных
Для фактовых данных эта проверка происходит очень быстро
Если с ячейкой связаны вычисления, может тормозиться в зависимости от
сложности формулы, т.к. чтобы сказать пуста она или нет, ее сначала нужно
рассчитать
Когда таких ячеек много, тормоза могут стать ощутимыми
Non_Empty_Behavior позволяет принять решение на основе проверки фактовых
данных
Create Member Measures.Profit As
Measures.Sales – Measures.Cost, Format_String = "Currency",
Non_Empty_Behavior = {Measures.Sales, Measures.Cost};
Filter(Customer.Members,
Customer.CurrentMember.Properties(“Gender”) = “Male”)
Exists(Customer.Members, Gender.[Male])
Закадровая функциональность Autoexists позволяет автоматически
исключать пустые комбинации при CrossJoin атрибутов
City.Seattle * State.Members = {(Seattle, WA)}
(Seattle, OR), (Seattle, CA) и т.п. заведомо не существуют и будут исключены
Ее также использует ф-ция Exists
Exists (Customer.Customer.Members, Customer.Gender.Male) = только клиенты мужского
пола
Требует, чтобы иерархия по атрибуту была enabled
Работает по атрибутам, относящихся к одному и тому же измерению
Внимание при проектировании измерений
Напр., а) включать Department атрибутом в измерение Employee или б) делать отдельным
измерением?
б) делает возможным анализ в новом срезе, но при этом лишаемся Autoexists для
быстрого получения всех сотрудников департамента
Create Member Measures.Sales As
Iif(Currency.CurrentMember Is Currency.USD,
Measures.SalesUSD, Measures.SalesUSD * Measures.XRate);
Create Member Measures.Sales As Null;
Scope(Measures.Sales, Currency.Members);
This = Measures.SalesUSD * Measures.XRate;
Scope(Currency.USA);
This = Measures.SalesUSD;
End Scope;
End Scope;
SCOPE предпочтительнее, т.к. в этом случае Query Execution
Engine заранее знает область вычислений для каждого бизнесправила и может выбрать оптимизированный путь выполнения над
этим диапазоном ячеек
Условия оцениваются динамически для каждой ячейки в области
Create Set RichCustomers As
Filter(Customer.Members,
CInt(Customer.CurrentMember.Properties(“Salary”))
> 100,000);
Create Set RichCustomers As
Filter(Customer.Members, Salary.MemberValue > 100,000);
MemberValue – внутреннее св-во члена, введенное в SQL Server 2005
Если таких ситуаций попадается много, имеет смысл рассмотреть
создание отдельной группы мер над таблицей измерения типа Salary или
Population
IIF ([Customer].[Company].Name = “Microsoft”, …
IIF ([Customer].[Company] IS [Microsoft], …
Сравнение IDов быстрее, чем сравнение строк
(Time.CurrentMember.PrevMember,Measures.CurrentMember).Value
Time.PrevMember
MDX-выражения оцениваются в каком-либо контексте
Контекст включает текущий член для каждой иерархии (по
умолчанию All)
Всегда, если не оговорено явно, задействуется CurrentMember
Специально указывать его не нужно – негативно сказывается на
производительности
Value – св-во ячейки, подразумеваемое по умолчанию. Также нет
нужды указывать его специально
Не стоит валить на него все подряд
Всегда лучше вычислять заранее во время
процессинга, чем на ходу во время запроса
По возможности перемещать вычисления из MDXскрипта в DSV
Именованные запросы
Вычисляемые колонки
Кроме того, SSAS 2005 обладает встроенными
возможностями поддержки достаточно замысловатых
сценариев
Неаддитивные меры, измерения «многие-ко-многим», ...
Прежде, чем писать custom MDX в скрипте, убедитесь,
что вы их задействовали по максимуму
При планировании MDX-вычислений над обширными областями с
многочисленными итерациями по возможности избегайте функций
позднего связывания
LinkMember, StrToSet, StrToMember, StrToValue, LookupCube
Они оцениваются во время выполнения, следовательно, Query
Execution Engine не в состоянии заранее отобрать эффективный
Еxecution Рath
Используйте Format_String вместо присвоения 0, Null, “N/A”, “-” и
т.д. пустым ячейкам
Примечание: клиентское приложение должно поддерживать это
свойство
Для выражений типа “expr1 * expr2” выражение, охватывающее
бОльшую область куба, лучше ставить слева
Sales * ExchangeRate вместо ExchangeRate * Sales
Sales * 1.15 вместо 1.15 * Sales
MDX-функция Aggregate предпочтительнее в вычислениях вместо
непосредственного указания Sum, Min, Max, ...
Microsoft SQL Server Analysis Services
http://www.microsoft.com/sql/technologies/analysis/default.mspx
Microsoft BI
http://www.microsoft.com/bi/default.aspx
Страница Ричарда Ткачука
http://sqlserveranalysisservices.com
Страница Моши Пасуманского
http://sqljunkies.com/weblog/mosha
Российская группа пользователей SQL Server
http://sql.ineta.ru
23 октября. Москва
Данила Корнев, Microsoft
"ADO.NET Entity Framework«
Иван Бодягин, RSDN
"LINQ и Linq 2 SQL в качестве lightweight ORM"
http://sql.ineta.ru/Events/EventInfo.aspx?ID=d2072a2d-cbc0-40f4-84d0a5ffd91bd0f6
31 октября. Ростов-на-Дону
Сергей Моисеенко, Южный Федеральный Университет
"Проект SQL-EX.RU и опыт использования Microsoft SQL Server "
Алексей Шуленин, Microsoft
"Новые возможности SQL в реализации Microsoft SQL Server 2008"
http://sql.ineta.ru/Events/EventInfo.aspx?ID=75f5d7c8-a02f-4930-9b5c3ca83887d770
http://sql.ineta.ru/Events/Events.aspx
© 2007 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.
The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market
conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation.
MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
Download