在SQL Server中,视图是一个保存的T-SQL查询。视图定义由SQL Server保存,以便它能够用作一个虚拟表来简化查询,并给基表增加另一层安全。但是,它并不占用数据库的任何空间。实际上,在你查询它之前,视图并不做任何事情。

索引视图

在SQL Server 2000和2005中,你能够给视图增加索引。但是,如果视图只是一个保存在数据库中的查询定义,在运行前没有自己的数据,你如何给那个定义建立一个索引呢?嗯,这比较麻烦。

索引视图是一个已被物化或保存在数据库中的视图。当基本表更新时,给视图建立的索引由数据库引擎保存和更新。当你的结果集返回许多行并且需要求总数时,索引视图十分有用。这是因为数据库引擎必须在基表数据更新时维持视图索引,这可能会降低事务的性能。

要给一个视图建立一个索引,视图定义必须遵守某组条件和会话设置,同时要求把基表和视图定义联系起来。如果你确定你的视图满足这些标准,你给视图建立的第一个索引必须是一个唯一的聚集索引,之后你可以给视图建立多个非聚集索引。建立的第一个视图必须在一组栏上,并且被聚集,以便索引被物化。

列表A说明如何建立一个索引视图。其中的脚本将建立SalesHistory表,并给它加载数据。

下面的代码将建立一个视图来概括表中的数据:

CREATE VIEW vw_salesbyproduct
AS
SELECT Product, COUNT_BIG(*) as ProductCount, SuM(SalePrice) as TotalSales FROMdbo.SalesHistory GROUP BY Product

由于它只是一个T-SQL查询定义,建立这个视图不用多少时间。建立好视图后,你就可以像对一个表一样对它进行查询。

SELECT Product, TotalSales, ProductCount
FROM vw_SalesByProduct
WHERE product = 'Computer'

如果你在SQL Server Management Studio或Query  Analyzer中设置选项来查看查询的“执行计划”(Execution  Plan),你会注意到上面的查询使用一个表扫描来找出Computer产品的总计结果。表扫描一般用于数据没有索引的情况下,它对整个结果集进行扫描以 找出需要的结果。

进行一些简单的改变,你就能够修改视图,以便你可以给它增加一个索引,从而改善搜索性能。首先,你必须设定下面的会话设置(注意必须要严格按照下面set语句的设置后,才能在视图上成功开启索引功能):

SET ANSI_NULLS ON
GO
SET ANSI_PADDING ON
GO SET ANSI_WARNINGS ON GO SET CONCAT_NULL_YIELDS_NULL ON GO SET QUOTED_IDENTIFIER ON GO SET NUMERIC_ROUNDABORT OFF GO --现在你可以建立自己的视图。为使事情更加简单,我建立一个崭新的视图。注意使用索引的视图在建立的时候必须要使用with schemabinding语句 CREATE VIEW dbo.vw_SalesByProduct_Indexed WITH SCHEMABINDING AS SELECT Product, COUNT_BIG(*) AS ProductCount, SUM(ISNULL(SalePrice,0)) AS TotalSales FROM dbo.SalesHistory GROUP BY Product GO --下面的脚本给我们的视图建立索引: CREATE UNIQUE CLUSTERED INDEX idx_SalesView ON vw_SalesByProduct_Indexed(Product) --为表明已经给视图建立一个索引,并且它确实占用数据库的空间,运行下面的脚本查明聚集索引有多少行以及视图占用多少空间。 EXECUTE sp_spaceused 'vw_SalesByProduct_Indexed' --下面的SELECT语句和以前的语句相同,只是这次它执行一个聚集索引搜索,这个过程完成得非常快。 SELECT Product, TotalSales, ProductCount FROM vw_SalesByProduct_Indexed WHERE Product = 'Computer'

加了视图索引后,没有命中索引?

当你完成上面的步骤后如果在视图上执行查询语句,有可能发现语句的执行计划还是用的Table Scan来扫描底层SalesHistory表,而不是用的Index Scan或Index Seek来使用我们上面在视图上加的索引idx_SalesView,这有可能是Sqlserver版本的问题,按照老外一篇文章的说法如果你的Sqlserver不是企业版就算建立了视图索引,但是在查询中也不会去使用视图索引,同时也有可能是Sqlserver查询分析器认为直接扫描底层表比用视图上的索引效率更高,所以导致你的查询语句没使用视图索引。这时我们可以使用WITH ( NOEXPAND )语句来告诉Sqlserver在查询中使用视图索引,语句如下:

SELECT
Product, TotalSales, ProductCount
FROM vw_SalesByProduct_Indexed WITH (NOEXPAND)
WHERE Product = 'Computer'

加了WITH ( NOEXPAND )语句后,上面的查询应该就会用到我们在视图vw_SalesByProduct_Indexed上建立的聚集索引idx_SalesView了。

这里有一篇老外的文章详细介绍了Sqlserver的视图索引,WITH ( NOEXPAND )语句也是这篇文章提到的,有空可以看看。

不要忘记性能测试

索引视图如果使用得当,它会十分有用,因为它们能够显著地提高查询的性能。但是,由于聚集索引增加的性能,数据库引擎必须在视图基表的所有事务过程 中维持那个索引。因为这个交换,建立一个索引视图可能对系统有益,也可能给系统造成伤害。确定这样做是有益还是有害的最佳方法就是进行全面的性能测试。

转载于:https://www.cnblogs.com/purple5252/p/11244619.html

SQLServer中在视图上使用索引(转载)相关推荐

  1. SQL2K数据库开发二十二之索引操作在视图上创建索引

    1.在企业管理器中,右击要创建索引的视图,在弹出的菜单中选择"设计视图"命令进入视图设计器.         2.在视图设计器中显示了视图所包含的列,定义视图的SQL语句以及视图中 ...

  2. 在 Oracle 中重建分区表上的索引

    在 oracle中,重建普通表上的索引很简单.要重建特定索引,只需执行如下sql命令: ALTER INDEX INDEX_NAME Rebuild; 这里,INDEX_NAME 代表索引的名字,下同 ...

  3. 细说Sql Server中的视图(下)转载

    原文:细说Sql Server中的视图(下)http://www.cnblogs.com/xbf321/archive/2009/06/19/view_two_in_sqlserver.html 1, ...

  4. oracle 视图能建索引吗,Oracle视图中建立索引注意事项.doc

    Oracle视图中建立索引的注意事项 在视图上创建索引需要三个条件:一.视图必须绑定到架构.要做到这点,在?CREATE?VIEW?语句中,必须加上?WITH?SCHEMABINDING,如果是使用企 ...

  5. 如何在ORACLE数据库的字段上建立索引?

    Oracle中建立索引,会提高查询速度: create index 索引名 on 表名(列名); 例如: create index index_userid on tbl_detail(userid) ...

  6. mysql 视图 union all 索引_mysql---索引、视图

    1. 索引 (1) 索引:表中一列或多列组合而成 作用:提高查询速度[降低了插入数据的速度] 所有存储引擎对每个表至少支持16个索引,总索引长度至少为256字节 InnoDB.MyISAM支持BTRE ...

  7. sqlserver中索引优化

    背景: MRO表中TimeStamp nvarchar(32),但实际上它存储的内容是日期(2015-09-09 11:20:30). 现在我要执行这样一个sql语句: Select t10.* fr ...

  8. 使用asp.net将图片上传并存入SqlServer中,然后从SqlServer中读取并显示出来

    一,上传并存入SqlServer  数据库结构   create table test   {      id identity(1,1),      FImage image   }   相关的存储 ...

  9. mysql中创建视图、索引

    数据库的三级模式两级映射: 存储文件------>基本表----->视图 内模式   ------->模式   ------>外模式 一.视图 1.什么是视图: 视图是从一个或 ...

最新文章

  1. 2019北京高考分数分布一览表(成绩分布统计)
  2. Windows Server2012 搭建域错误“本地Administraor账户不需要密码”
  3. UINavigationController
  4. 8、路由 router
  5. Leetcode-SingleNumberII
  6. 保留小数点后三位_三年后想买车?Excel理财小助手pmt函数帮你算
  7. Atitit sumdoc everything index tech and index log 目录 1. 使用的tech 1 1.1. Atitit 日志记录的三个trace跟踪等级文件夹级
  8. jQuery知识点学习整理
  9. 买二手iphone的建议
  10. pycharm 输入法光标跟随
  11. vue3.0 ele-plus 与 antd-design的使用
  12. android 放大镜功能,利用Android实现一个放大镜功能
  13. 《基于多任务神经网络的语种识别研究》——秦晨光
  14. unity shader中关于Tags的整理
  15. Encoded password does not look like bcrypt
  16. Win10安装fliqlo时钟屏保教程
  17. springMVC源码之组件介绍
  18. python实现贪吃蛇小游戏
  19. matlab如何求矩阵特征值
  20. 数据库For Web

热门文章

  1. BZOJ 2440 完全平方数
  2. oracle发生重启动的介绍
  3. Activity启动模式和FLAG、TASKAFFINITY
  4. android 添加新用户,华为手机怎么添加新用户?华为手机添加新用户的方法
  5. qq手机电脑消息同步_这届用户换机首选必备工具,QQ同步助手一键迁移手机资料...
  6. linux进入超级管理员权限,一直处于超级管理员权限下
  7. python闭包(一分钟读懂)
  8. 找不到服务器micro,Go Micro服务发现
  9. android每秒 1,在Android 5.1中调度每秒的警报
  10. python cryptography key加密_python3利用cryptography 进行加密和解密