【问题标题】:How can I optimize views in SQL Server for speed如何优化 SQL Server 中的视图以提高速度
【发布时间】:2011-02-13 16:34:16
【问题描述】:

我已经为我的项目创建了视图。现在我想优化它们以提高速度...如何确定视图可以优化?索引对此有用吗?

让我们说下面的例子......

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_webTopBidsvm_WebInventory 是两个不同的视图...

是否可以优化此视图?

【问题讨论】:

    标签: sql performance tsql view sql-server-2005


    【解决方案1】:

    视图是扩展为外部查询的宏。除非它是索引视图并且您拥有企业版,否则它会被忽略。

    因此,如果您连接 3 个视图并且每个视图使用 5 个表,那么您就有 15 个表的大连接。

    您最好选择Database Tuning Advisor 或缺少索引脚本:

    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
    

    在示例之后编辑

    您将视图嵌套在视图之上。视图本身无法优化。

    如前所述,无法编入索引

    【讨论】:

    • 视图加索引对优化速度有用吗?
    • @girish:没有更多信息很难说。就个人而言,在考虑索引视图之前,我会使用 DTA 或上面的脚本
    • 索引视图可用于企业版以外的 SQL Server 版本,但您必须在任何引用视图的查询中提供 NOEXPAND 提示,否则索引将被忽略。
    【解决方案2】:

    在这种情况下,视图无法被索引,因为它包含一个 OUTER JOIN。

    有关索引视图及其(许多)限制的信息,请参阅本文:http://technet.microsoft.com/en-us/library/cc917715.aspx

    【讨论】:

    • 是这个意思吗,上面的视图是完美的......它不能再优化了
    • 依赖太多了。正如其他地方所建议的,首先考虑优化基础表。如果访问模式需要广泛使用视图以便改进此视图将带来最大的好处,请查看是否可以更改它以使其满足索引视图约束,然后添加适当的索引。
    【解决方案3】:

    调用其他视图的嵌套视图是一种非常糟糕的性能技术。由于它不能被索引,它必须调用整个底层视图才能获得顶部将返回的一条记录。另外,最终您获得了足够的层,并且您达到了可以在视图中调用多少表的限制(如果 view1 调用 view2 和 view3 并且都调用相同的基础表,那么您将加入它们两次而不是一次,这通常对性能。停止从视图调用视图,否则你很快就会有一个无法使用的系统。

    我们正在完全重新设计这样的系统,因为应用程序开发人员这样做了,价值数百万美元的客户将离开我们,除非性能得到改善,而且我们无法用这种结构改进它,所以现在我们面临一个由于错误是我们的错误,因此客户不会支付的完全重新设计。不要走这条路。现在停下来。调用视图的视图非常非常糟糕。

    【讨论】:

    • @HLGEM 由于您的回答已有 8 年以上的历史,我想再次检查来自不同数据库的视图调用表和其他视图是否在最新的 SQL Server 版本中进行了优化?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多