Как я могу оптимизировать представления в SQL Server для скорости - PullRequest
6 голосов
/ 29 апреля 2010

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

let's say the following example...

    SELECT        dbo.vw_WebInventory.skref AS SaleID, dbo.vw_WebInventory.lot_number AS LotNumber, dbo.vw_WebInventory.Description, 
                             dbo.vw_WebInventory.Image AS HasImage, dbo.vw_WebInventory.Sold, dbo.vw_WebInventory.Withdrawn, dbo.vw_WebTopBids.TopBid, 
                             ISNULL(dbo.vw_WebInventory.Mins_Extend_y, 0) AS BidTimeExtend, dbo.Sale.SaleTypeID, dbo.Sale.ClosingDate, dbo.vw_WebInventory.ExDate, 
                             dbo.vw_WebInventory.CurrDate, CASE WHEN vw_WebInventory.ExDate > ISNULL(vw_WebInventory.LotClosingDate, Sale.ClosingDate) 
                             THEN 1 ELSE 0 END AS ShowBidMessage
    FROM            dbo.vw_WebInventory INNER JOIN
                             dbo.Sale ON dbo.vw_WebInventory.skref = dbo.Sale.SaleID LEFT OUTER JOIN
                             dbo.vw_WebTopBids ON dbo.vw_WebInventory.skref = dbo.vw_WebTopBids.CatNumber AND dbo.vw_WebInventory.lot_number = dbo.vw_WebTopBids.LotNumber

где vm_webTopBids и vm_WebInventory - это два разных представления ... возможно ли оптимизировать это представление?

Ответы [ 3 ]

19 голосов
/ 29 апреля 2010

Вложенные представления, которые вызывают другие представления, являются чрезвычайно плохой техникой для производительности. Поскольку он не может быть проиндексирован, он должен вызвать весь базовый вид, чтобы получить одну запись, которую вернет вершина. Кроме того, в конечном итоге вы получаете достаточно слоев и достигаете предела количества таблиц, которые вы можете вызвать в представлении (и если view1 вызывает view2 и view3 и обе вызывают одни и те же базовые таблицы, вы присоединяетесь к ним дважды, а не один раз, что часто плохо для производительность. Прекратите вызывать представления из представлений, иначе у вас очень скоро будет неиспользуемая система.

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

3 голосов
/ 29 апреля 2010

Представление - это макрос, который раскрывается во внешний запрос. Если это не индексированное представление, а у вас корпоративная версия, оно просто игнорируется.

Таким образом, если вы объединяете 3 представления и каждое из них использует 5 таблиц, вы получаете большое объединение с 15 таблицами.

Лучше всего ставить советник по настройке базы данных 1006 * или отсутствующий индексный скрипт:

SELECT
    CONVERT(decimal(28, 1), migs.avg_total_user_cost * migs.avg_user_impact *
    (migs.user_seeks + migs.user_scans)) AS improvement_measure,
    'CREATE INDEX missing_index_' + CONVERT(varchar, mig.index_group_handle) +
    '_' + CONVERT(varchar, mid.index_handle) + ' ON ' + mid.statement + ' (' +
    ISNULL(mid.equality_columns, '') +
    CASE WHEN mid.equality_columns IS NOT NULL AND
              mid.inequality_columns IS NOT NULL THEN ','
         ELSE ''
    END + ISNULL(mid.inequality_columns, '') + ')' + ISNULL(' INCLUDE (' +
                                                            mid.included_columns +
                                                            ')', '') AS create_index_statement,
    migs.*,
    mid.database_id,
    mid.[object_id],
    mig.index_group_handle,
    mid.index_handle
FROM
    sys.dm_db_missing_index_groups mig INNER JOIN 
    sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle INNER JOIN
    sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle
WHERE
    CONVERT(decimal(28, 1), migs.avg_total_user_cost * migs.avg_user_impact *
    (migs.user_seeks + migs.user_scans)) > 10 AND
    database_id = DB_ID()
ORDER BY
    migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks +
                                                       migs.user_scans) DESC

Редактировать, после примера

Вы вкладываете представления поверх представлений. Оптимизация самого представления невозможна.

Как уже упоминалось, это не может быть проиндексировано

2 голосов
/ 29 апреля 2010

В этом случае представление не может быть проиндексировано, поскольку оно содержит OUTER JOIN.

См. Эту статью для получения информации об индексировании представлений и (многих) ограничений на них: http://technet.microsoft.com/en-us/library/cc917715.aspx

...