参考:http://blog.csdn.net/eriato/article/details/41039985

http://blog.sina.com.cn/s/blog_71247658010183j6.html

(大概摘一些,,,,重点是了解这概念,用法可以慢慢找)

索引视图

索引视图有助于提高 T-SQL 的性能

Itzik Ben-Gan

T-SQL 是一种允许您以逻辑方式设计请求的语言。这里所说的“逻辑”的意思是,当编写查询时,您指定的是希望获得什么 结果,而不是希望以何种方式 获得结果。对如何处理查询进行设计是查询优化器的工作。您所遇到的需要 T-SQL 解决方案的每个问题通常都有许多不同的解决方案,它们最终会返回同样的结果。在理想情况下,假设有两个执行同一任务的不同查询,优化器会为二者生成相同的执行计划 - 最优化的计划。SQL Server 开发组似乎正在朝这个方向努力。利用 SQL Server 的每个发行版本,优化器会设计出更高级、更有效的计划,执行同一任务的不同查询使用这个相同计划的可能性也在提高。

不过,在许多情况下,您编写查询的方式仍然会动态地影响查询的性能。为了使优化器在不同的计划中作出选择并找到一个高效的计划,您需要完成一些准备工作 - 也就是,创建索引。大多数人是将普通索引作为其数据库优化的一部分创建的,但我还没有看到索引视图的广泛实现。索引视图可以极大地提高查询性能,尤其在聚合数据的时候。在某些情况下,对视图进行创建并索引后,您甚至不需要更改引用基表的原始查询,这是因为优化器的智能程度足以使用那些索引。

下面我们将讨论使用索引视图来获得性能提高的两个问题。我假设您已经很熟悉索引视图的基本概念。(有关索引视图的详细信息,请参阅 Kalen Delaney 的 "Introducing Indexed Views" (2000 年 5 月发表,InstantDoc ID 8410)一文。)

关于新客户的问题

第一个问题涉及一个典型的市场营销请求 - 在每个期间(例如,月份),根据定单活动而定的新客户、现有客户和全部客户的数量分别是多少?某个月的新客户就是第一次下达定单的客户。现有客户是那些在以前的月份下达过定单的客户。您可以将 Northwind 数据库中的 Orders 表作为最初的基本数据。表 1(表 1)显示了预期输出的简化版本。创建解决方案并验证您的代码在逻辑上正确无误之后,可针对一个更大的 Orders 表测试其性能,您可以通过运行第 18 页 清单 1 显示的代码,在 tempdb 中创建该表。

第 18 页 清单 2 显示了我针对此问题的第一个解决方案。定义派生表 M 的最内部查询从 Orders 返回了不同的月份和客户组合。月份表示为指向当月第一天的一个 datetime 值。定义派生表 N 的查询使用 CASE 表达式,对于每个月份和客户组合,如果该客户在当月之前还没有下达过定单,则该表达式返回 1,否则,返回 0。也就是说,如果客户是新客户,CASE 表达式返回 1。最外部查询按月份对 N 中的行进行分组,并通过对 N 表中名为 new 的列中的所有 1 进行汇总,来计算新客户的总数。客户的总数就是该组中的行数 (COUNT(*)),因为该组中的每一行都代表一个不同的客户。现有客户的数量是客户总数减去新客户的数量。

当我编写此解决方案时,我并没有考虑性能,我只想到要用逻辑方式来编写该查询。在我的笔记本电脑上,对我在 tempdb 中创建的较大的 Orders 表运行该查询时,该查询发生了超过 137,000 次的逻辑读取,运行的时间长达 17 秒。普通索引并没有提供多少帮助 - 当我在 customerid 列和 orderdate 列上创建了组合索引后,该查询运行了 15 秒。看来,这个问题需要采用另一种方法,这次,我决定先考虑性能。

这个较大的 Orders 表会包括每个月份的每个客户的许多定单。如果您有一个只包含月份和客户的不同组合的汇总表,就可以编写一个更易于执行的查询。索引视图的实质就是对表进行汇总。请运行 清单 3 中的代码,创建一个名为 Vymcusts 的索引视图,该视图只包含月份和客户的不同组合。注意,如果您希望对一个使用聚合的视图进行索引,则必须在该视图内包括 COUNT_BIG(*) 函数。如果 SQL Server 知道每组中的行数,就可以有效地维护索引视图。

接下来,我测试了几个不同的解决方案,所有方案执行起来都比第一个要好得多。我们来看一下我编写出的执行效果最好的解决方案。我创建了另一个名为 Vnewcusts 的视图,该视图包含每个客户的最小年/月份 (ym) 值:

CREATE VIEW Vnewcusts
AS
SELECT customerid, MIN(ym) AS min_ym
FROM Vymcusts (NOEXPAND)
GROUP BY customerid

客户的 ym 最小值就是该客户的第一份定单的月份。NOEXPAND 提示要求优化器将索引视图视为表,不要尝试使用来自基表 Orders 的索引。最后,我将 Vymcusts (VY) 左联接到了 Vnewcusts (VN)。如果 VY 和 VN 同时拥有同一个客户,并且 VY 中的当前月份是该客户的最小月份 (VY.ym = VN.min_ym),则 VY 中的某一行会在 VN 中寻找匹配的行。如果该月份不是该客户的最小月份,则外部联接在 VN.customerid 中以及在 VN 的所有列中均返回 NULL。查询按 VY.ym 列对外部联接的结果进行分组。SQL Server 通过对 VN.customerid 中的非 Null 值进行计数来计算新客户的总数。清单 4 显示了这个最终的查询,该查询在我的笔记本电脑上只运行了 1 秒,仅发生了 280 次逻辑读取。这样的性能令人非常满意。

-()

视图在数据库开发过程中是非常重要的,对提高查询速度有很大的提高。因此我们的学会创建视图,并且有效的使用视图。
(1)表准的SQL视图
标准视图比较简单,大家也都在使用,在此就不垒述了。
(2)使用动态视图
标准视图有一个严重的局限性,那就是标准视图不支持参数。俗话说“法网恢恢,疏而不漏”,呵呵,我们也可以变通的使用带参数的视图。实现方法是我们把一个用户定义的表值函数当作支持参数的动态视图使用:
CREATE FUNCTION fnTestView (@m_id int)
RETURNS TABLE
AS
RETURN (select * from 视图名称 where 条件=@m_id)
这样可以在Select语句的From子句中引用他们,用法:
Select * from fnTestView(2)

(3)使用索引视图
我们在使用视图的时候有时想怎么能给视图加索引呢,其实,视图和普通的表一样可以添加索引,当SQL Server必须联合很多表时,这项技术可以大大提高Select语句的性能。
当在视图上创建一个唯一聚集索引(unique clusterd index)时,SQL Server将物化这个视图。看下面的例子:
CREATE VIEW dbo.vtUsers
WITH SCHEMABINDING
AS
SELECT dbo.tUsers.userid, dbo.tUsers.username, dbo.tUsers.password,
dbo.tUsers.question, dbo.tUsers.answer, dbo.tUsers.email, dbo.tUsers.realname,
dbo.tUsers.sex, dbo.tUsers.birthday, dbo.tUsers.country, dbo.tUsers.city,
dbo.tUsers.address, dbo.tUsers.zip, dbo.tUsers.tele, dbo.tUsers.exdate,
dbo.tUsers.totalfund, dbo.tUsers.ordertotal, dbo.tUsers.jifen, dbo.tUsers.pid,
dbo.tUsers.agentid, dbo.tUsers.agentid2, dbo.tUsers.agentid3, dbo.tUsers.status,
dbo.tUsers.checkmod, dbo.tUsers.account, dbo.tUsers.bank, dbo.tUsers.logip,
dbo.tUsers.sitename, dbo.tUserInfo.siteurl
FROM dbo.tUsers INNER JOIN
dbo.tUserInfo ON dbo.tUsers.userid = dbo.tUserInfo.userid
WHERE dbo.tUserInfo.UserID >20

CREATE UNIQUE CLUSTERED INDEX idxvtUser
ON vtUsers(userid)

尽管这个索引只引用了列的一个子集,但是这个索引包含叶级别节点中的所有列(每个聚集索引也都是这样)。
和标准视图一样索引视图的创建和使用也都是有限制的。一个标准视图转换为一个索引视图必须遵守以下规则:
A.视图必须使用With Schemabinding选项来创建;
B.在这个视图中不能使用其他视图、导出表、行集函数或自查询,也就是说只能使用表;
C.视图所用到的基本表必须和视图属于同一个所有者;
D.视图只能链接同一个数据库中的表;
E.视图不能包含一个外部链接或自链接,也就是说在链接表时只能使用INNER JOIN并且INNER JOIN前后不能使同一个表,不能使用LEFT(RIGHT) JOIN 或者 LEFT (RIGHT) OUTER JOIN ;看下面的例子:
比如说创建了下面的视图(自链接):
CREATE VIEW dbo.vtUsers
WITH SCHEMABINDING
AS
SELECT dbo.tUsers.userid, dbo.tUsers.username, dbo.tUsers.password,
dbo.tUsers.question, dbo.tUsers.answer, dbo.tUsers.email, dbo.tUsers.realname
FROM dbo.tUsers Inner join
dbo.tUsers as t ON dbo.tUsers.userid = t.userid
这个视图是可以创建的,但是在创建索引时CREATE UNIQUE CLUSTERED INDEX idxvtUser ON vtUsers(userid) 就会出错了;
再看下面的视图(外部连接):
CREATE VIEW dbo.vtUsers
WITH SCHEMABINDING
AS
SELECT dbo.tUsers.userid, dbo.tUsers.username, dbo.tUsers.password,
dbo.tUsers.question, dbo.tUsers.answer, dbo.tUsers.email, dbo.tUsers.realname
FROM dbo.tUsers LEFT OUTER JOIN
dbo.tUserInfo ON dbo.tUsers.userid = dbo.tUserInfo.userid
在创建索引时也会出错的。
F. 视图不能包含UNION子句、TOP子句、ORDER BY子句、Having子句、Rollup子句、Cube子句、compute子句、Compute By子句或Distinct关键字;
G. 视图不允许使用某些集合函数,如:Count(*)可以使用count_big(*)代替、avg()、max()、min()、stdev()、stdevp()、var()或varp()等;
H. 视图不能使用Select * 这样的语句,也就是说视图的所有字段都必须显示指定;
I. 视图不能包含Text、ntext、image类型的列;
J. 如果视图包含一个Group By子句,那么他必须在Select列中包含count_big(*);
K. 视图中的所有标和用户自定义的函数都必须使用两段式名来引用,即所有者.表或函数名称;
L. 所有的基本表和视图都必须使用 Set Ansi_Nulls On 创建;
M. 在创建索引时或创建索引后执行IUD时,必须显示或隐式地执行:
Set ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
SET ARITHABORT ON
SET CONCAT_NULL_YIELDS_NULL ON
SET QUOTED_IDENTIFIER ON
SET NUMERIC_ROUNDABORT OFF
各个选项的有关信息或意义,可以查阅SQL Server的联机丛书,这里就不再介绍了;
N. 索引视图只有在SQL Server2000的企业版或开发版或者更高的版本中才能创建。
如果一个视图可以添加唯一聚集索引,那么在添加了唯一聚集索引之后,该视图也可以像数据库表一样添加非聚集索引,CREATE INDEX idxvtUsers ON vtUsers(username,realname)。

转载自http://www.cnblogs.com/fineboy/archive/2005/09/14/236731.html

转载于:https://www.cnblogs.com/ijunxiong/articles/7592741.html

数据库视图优化概念,索引视图,物化视图相关推荐

  1. oracle物化视图可以创建索引,oracle 物化视图及创建索引

    物化视图是一种特殊的物理表,"物化"(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,Oracle都实际上转换为视图SQL语 ...

  2. oracle access advisor,使用Oracle SQL Access Advisor改善数据库索引与物化视图

    当针对表集增加物化视图(materialized view)和索引时,理论上这些表的查询性能会得到改善.但事实上并不一定能达到理想的状态,因此Oracle推出了SQL Access Advisor工具 ...

  3. oracle物化视图trunc,转载:oracle物化视图介绍

    -- 创建一个基表SQL>CREATETABLETTT1(AINTPRIMARYKEY,BINT);Tablecreated.-- 以TTT1为基表创建一个可更新的MViewSQL>CRE ...

  4. drop 很慢 物化视图_终于解决了物化视图复制的问题

    今天真是个高兴的日子.刚回到公司就被技术总监拉了过去,给我展示研发的最近成果.好久没看到他如此轻松的神情,因为就在今天,一个关键的技术问题 -- 物化视图 materialized view--被他搞 ...

  5. oracle查看物化视图的索引,oracle – 物化视图中的域索引返回零行

    我有Oracle DB的问题 – 在物化视图上通过CONTAINS()搜索后,域索引返回零行.我看到物化视图充满了数据,我还使用过程ctx_ddl.sync_index()进行域索引同步. 什么有用: ...

  6. Oracle物化视图:创建最简单物化视图

    物化视图是一种特殊的物理表,"物化"(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,oracle都实际上转换为视图SQL语 ...

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

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

  8. oracle视图如何创建索引,ORACLE 创建视图索引序列

    /* 视图View 视图是从若干基本表和(或)其他视图构造出来的表 视图存放的都是查询语句,并没有真实的数据 虚表 作用 限制对数据的操作 复杂查询变简单 提供相同数据的不同显示 UNION ALL ...

  9. mysql中视图的概念_MySql中的视图的概念及应用

    视图的基本概念 视图是从一个或几个基本表(或者视图)导出的表.它与基本表不同,是一个虚表. 数据库只存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中.所以基本表中的数据发生变化, ...

最新文章

  1. 微信小程序图片上传到服务器再自动替换,微信小程序批量上传图片到服务器,并实现预览,删除功能...
  2. python处理csv数据-python 数据处理 对csv文件进行数据处理
  3. 《编程能力基础》刷题笔记(41 题)
  4. PHP 的魔术方法及其应用
  5. 23种设计模式(六)单一职责之桥模式
  6. 数据库入门-主键和外键设置
  7. dota2国服服务器延迟高,为何dota2国服经常崩溃 竟然是良心不分区的原因
  8. 数据安全管理条例明确个人信息保护 360呼吁隐私保护重在企业
  9. SpringBoot实现文件上传和下载
  10. java关键字super指什么_java 关键字super详解及用法
  11. 关于开机自启动qbo服务的讨论
  12. 哪些大学食堂好吃?各大高校大比拼!
  13. 求解某项目的关键路径和总工期
  14. Android屏幕点亮(常亮)及屏幕解锁和锁定
  15. 网页素材精品:40套很漂亮的纹理背景图片
  16. [Error]EOL while scanning string literal
  17. unity手游使用terrian注意事项
  18. 粒子效果 Particles
  19. 智慧城市建设风起云涌 视频监控应如何接招?
  20. BiLiBiLi爬虫

热门文章

  1. ❤️❤️爆肝3万字整理小白入门与提升分布式版本管理软件:Git,图文并茂(建议收藏)❤️❤️
  2. matlab在通信中的应用实验指导书 课后答案,《MATLAB及Simulink应用》实验指导书+答案...
  3. 如何挖掘和策划公关传播内容,不再局限于新闻稿
  4. 产品APP架构说明文档
  5. 大数据24小时:小米与微软就云计算等达成合作,哈佛大学发明爬行机器人用于医疗搜救
  6. PostgreSQL处理jsonb中的arrays of array 类型
  7. 鸿蒙和yunso区别,华为没消息反而多家媒体之间相互作为依据报道,鸿蒙OS到底几家真?...
  8. 第十五届全国大学生智能汽车竞赛-双车组三轮图像处理总结(已开源)
  9. Zeppelin与Linkis、Scriptis的实践对比
  10. vue-10 数据监测watch自学视频