sqlserver 建立索引视图各问题!
发布时间:2020-12-12 14:23:34 所属栏目:MsSql教程 来源:网络整理
导读:--我的 tab 表有 60398 条数据,大家可以用自己的任意表测试SELECT * FROM tab GO--新建表MYTABLE,带序号IF object_id(N'[dbo].[MYTABLE]') IS NOT NULL drop table MYTABLESELECT IDENTITY(INT,1,1) ID,* INTO MYTABLE FROM tabGO SELECT * FROM MYTABLE--CR
--我的 tab 表有 60398 条数据,大家可以用自己的任意表测试 SELECT * FROM tab GO --新建表MYTABLE,带序号 IF object_id(N'[dbo].[MYTABLE]') IS NOT NULL drop table MYTABLE SELECT IDENTITY(INT,1,1) ID,* INTO MYTABLE FROM tab GO SELECT * FROM MYTABLE --CREATE CLUSTERED INDEX PRIMARYKEY ON MYTABLE(ID) --if exists(select * from sysindexes where id=object_id('MYTABLE') and name='PRIMARYKEY') --建立分割表,把MYTABLE中的数据划分到两个表中,用凉表做测试 IF object_id(N'[dbo].[MYTABLE_TOP50PERTCENT]') IS NOT NULL drop table MYTABLE_TOP50PERTCENT IF object_id(N'[dbo].[MYTABLE_LAST50PERTCENT]') IS NOT NULL drop table MYTABLE_LAST50PERTCENT SELECT TOP 50 PERCENT * INTO MYTABLE_TOP50PERTCENT FROM MYTABLE SELECT * INTO MYTABLE_LAST50PERTCENT FROM MYTABLE WHERE ID NOT IN (SELECT ID FROM MYTABLE_TOP50PERTCENT) GO --建立联合视图(这个建法不正确,等下改正) IF object_id(N'[dbo].[VW_MYTABLE_ALL]') IS NOT NULL DROP VIEW VW_MYTABLE_ALL GO CREATE VIEW dbo.VW_MYTABLE_ALL --WITH SCHEMABINDING /*如添加WITH SCHEMABINDING,则表必须带架构名,如dbo.MYTABLE_TOP50PERTCENT*/ AS SELECT * FROM MYTABLE_TOP50PERTCENT UNION ALL SELECT * FROM MYTABLE_LAST50PERTCENT GO --查询视图,对表扫描 SELECT * FROM VW_MYTABLE_ALL --对分割表创建索引,对视图的查询会转向表的查询 if exists(select * from sysindexes where id=object_id('MYTABLE_TOP50PERTCENT') and name='PRIMARYKEY1') drop INDEX MYTABLE_TOP50PERTCENT.PRIMARYKEY1 if exists(select * from sysindexes where id=object_id('MYTABLE_LAST50PERTCENT') and name='PRIMARYKEY2') drop INDEX MYTABLE_LAST50PERTCENT.PRIMARYKEY2 CREATE CLUSTERED INDEX PRIMARYKEY1 ON MYTABLE_TOP50PERTCENT(ID) CREATE CLUSTERED INDEX PRIMARYKEY2 ON MYTABLE_LAST50PERTCENT(ID) --查询视图,此时使用索引查询 SELECT * FROM VW_MYTABLE_ALL --删除表的索引,建立视图索引 if exists(select * from sysindexes where id=object_id('MYTABLE_TOP50PERTCENT') and name='PRIMARYKEY1') drop INDEX MYTABLE_TOP50PERTCENT.PRIMARYKEY1 if exists(select * from sysindexes where id=object_id('MYTABLE_LAST50PERTCENT') and name='PRIMARYKEY2') drop INDEX MYTABLE_LAST50PERTCENT.PRIMARYKEY2 CREATE UNIQUE CLUSTERED INDEX IND_VW_MYTABLE ON VW_MYTABLE_ALL(ID ASC) go --错误:无法对视图 'VW_MYTABLE_ALL' 创建 索引,因为该视图未绑定到架构 --解决:因此之前创建的视图应该为这样,将视图绑定到架构 IF object_id(N'[dbo].[VW_MYTABLE_ALL]') IS NOT NULL DROP VIEW VW_MYTABLE_ALL GO CREATE VIEW dbo.VW_MYTABLE_ALL WITH SCHEMABINDING AS SELECT * FROM dbo.MYTABLE_TOP50PERTCENT UNION ALL SELECT * FROM dbo.MYTABLE_LAST50PERTCENT GO --错误:在绑定到架构的对象中不允许使用语法 '*'。 --解决:必须把视图中的查询列名写出,如下 IF object_id(N'[dbo].[VW_MYTABLE_ALL]') IS NOT NULL DROP VIEW VW_MYTABLE_ALL GO CREATE VIEW dbo.VW_MYTABLE_ALL WITH SCHEMABINDING AS SELECT ID,ProductKey,CustomerKey,OrderDateKey,UnitPrice,UnitPriceDiscountPct FROM dbo.MYTABLE_TOP50PERTCENT UNION ALL SELECT ID,UnitPriceDiscountPct FROM dbo.MYTABLE_LAST50PERTCENT GO --创建视图索引 CREATE UNIQUE CLUSTERED INDEX IND_VW_MYTABLE ON dbo.VW_MYTABLE_ALL(ID ASC) ON ps_OrderDateKey(id) go /* !!仍有错误: 无法对视图 'Sales_DW.dbo.VW_MYTABLE_ALL' 创建 索引,因为其中包含一个或多个 UNION、INTERSECT 或 EXCEPT 运算符。 如果将查询作为原始视图的 UNION、INTERSECT 或 EXCEPT 运算符的输入,请考虑为每个这样的查询创建一个单独的索引视图。 */ /*==========================================================================================*/ /*==========================================================================================*/ --白忙一场!!视图索引只对单个查询建立,一下以MYTABLE看看 IF object_id(N'[dbo].[VW_MYTABLE]') IS NOT NULL DROP VIEW VW_MYTABLE GO CREATE VIEW dbo.VW_MYTABLE WITH SCHEMABINDING AS SELECT ID,UnitPriceDiscountPct FROM dbo.MYTABLE GO if exists(select * from sysindexes where id=object_id('VW_MYTABLE') and name='IND_MYTABLE') drop INDEX VW_MYTABLE.IND_MYTABLE CREATE UNIQUE CLUSTERED INDEX IND_MYTABLE ON dbo.VW_MYTABLE(ID ASC) go SELECT * FROM VW_MYTABLE SELECT * FROM MYTABLE <strong><span style="font-size:14px;">--网上查到的各约束规则</span></strong> /* 一个标准视图转换为一个索引视图必须遵守以下规则: A.视图必须使用With Schemabinding选项来创建; 如果创建视图时没有with Schemabinding,试图创建视图时就会报错:……因为该视图未绑定到架构 B.在这个视图中不能使用其他视图、导出表、行集函数或自查询,也就是说只能使用表; C.视图所用到的基本表必须和视图属于同一个所有者; D.视图只能链接同一个数据库中的表; E.视图不能包含一个外部链接或自链接,也就是说在链接表时只能使用INNER JOIN并且INNER JOIN前后不能使同一个表,不能使用LEFT(RIGHT) JOIN 或者 LEFT (RIGHT) OUTER JOIN ; 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 N.索引视图只有在SQL Server2000的企业版或开发版或者更高的版本中才能创建。 在一个表上创建了索引视图后,对其执行delete操作时报错:DELETE 失败, 因为下列 SET 选项的设置不正确: 'CONCAT_NULL_YIELDS_NULL,ANSI_PADDING,ARITHABORT',删除这个视图问题就解决了 */ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |