Индексированное представление заставляет неоптимальный тип столбца - PullRequest
1 голос
/ 16 марта 2012

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

Time.UserID is INT
Time.TimeUnit is DECIMAL(9,2)
Time.BillingRate is MONEY

Select 
    UserID, 
    SUM(TimeUnit) as Hours, 
    SUM(TimeUnit*BillingRate) as BillableDollars
FROM 
    Time
GROUP BY 
    UserID

дает нам представление со столбцами:

UserID(int, null)  
Hours(decimal(38,2), null)  
BillableDollars(decimal(38,6), null)

Мы бы предпочли иметь Hours(decimal(9,2),null) и BillableDollars(money,null).

CAST(SUM(TimeUnit*BillingRate) AS MONEY) as BillableDollars

Возвращено:

Невозможно создать кластеризованный индекс 'ix_indexName' для представления 'x.dbo.vw_viewName', поскольку список выбора представления содержит выражение для результата статистической функции или столбца группировки.Попробуйте удалить выражение для результата статистической функции или столбца группировки из списка выбора.

И нас беспокоит эффективность SUM(CAST(TimeUnit*BillingRate AS MONEY)) as BillableDollars

Каков наилучший способ сохранить этитипы столбцов или есть «лучшая практика»?

Ответы [ 2 ]

2 голосов
/ 16 марта 2012

Я мог бы попытаться добавить производный (актуализированный) столбец «BillableDollars» в таблицу «Время» с примененным преобразованием:

CONVERT(MONEY,(TimeUnit*BillingRate))

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

Я полагаю, что это позволит вам иметь индексированное представление при суммировании рассчитанных оплачиваемых долларов.

Я ожидаю, что причина того, что вы получаете большую точность в типе данных представления, чем в типе данных таблицы, заключается в том, что сумма набора чисел с точностью до 9 суммируется с числом, которое нуждается в точность больше 9.

0 голосов
/ 16 марта 2012

Просто поместите ваше индексированное представление во второе представление «приведение», как это

CREATE VIEW MyView
AS
SELECT  CAST(UserID AS INT)              AS UserID
        , CAST(TimeUnit AS DECIMAL(9,2)) AS TimeUnit
        , CAST(BillingRate AS MONEY)     AS BillingRate
FROM    MyViewIndexed WITH (NOEXPAND)

В качестве бонуса вы можете включить подсказку NOEXPAND, чтобы базовое индексированное представление фактически использовалось оптимизатором запросов на менее «продвинутом»издания MSSQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...