浅谈SQL Server索引视图(物化视图)以及索引视图与查询重写

news2025/1/18 17:11:44

目录

(一)前言

(二)正文

1. 物化视图(索引视图)与查询重写的基本概念

2. 创建测试环境

(1)建表

(2)写数据

3. 索引视图创建

(1)创建语法

(2)为索引视图创建索引

 4. 查询重写

5. 为什么查询会被重写

 6. 索引视图什么时候更新

7. 改变基于视图的查询


(一)前言

之前做ORACLE DBA的时候,在参与业务涉及中常会遇到物化视图这个概念,同样在SQL SERVER中也有类似于ORACLE的物化视图的功能,只是名称变成了索引视图。本文我们将采用SQL SERVER来谈一谈索引视图(物化视图)以及基于此的查询重写。

(二)正文

1. 物化视图(索引视图)与查询重写的基本概念

与普通视图比,物化视图就是直接将数据存储起来了。而物化视图的作用之一就是可以实现查询重写。SQL Server中的索引视图就具有查询重写的功能,所谓的查询重写,就是如果符合条件的数据在索引视图上,并且查询列都包含在在索引视图上,此时可以直接通过查询索引视图来替代基于原始表的查询。

2. 创建测试环境

(1)建表

创建两张表,一张表头TESTZYY,一张明细TESTLMN,仅仅作为DEMO使用

--创建两张表,一张表头TESTZYY,一张明细TESTLMN,仅仅作为DEMO使用
CREATE TABLE TESTZYY
(
    HeadId      INT PRIMARY KEY  ,
    HeadInfo    VARCHAR(50)      ,
    DataStatus  TINYINT          ,
    CreateDate  Datetime
)
GO;

CREATE TABLE TESTLMN
(
    HeadId      INT           ,
    DetailId    INT identity(1,1) PRIMARY KEY ,
    DetailInfo  VARCHAR(50)
)
GO;

(2)写数据

给上一步中创建的两个表各插入20万条数据。

--写入数据
DECLARE @i int = 0
WHILE @i<200000
BEGIN
    INSERT INTO TESTZYY values (@i,NEWID(),RAND()*10,GETDATE()-RAND()*100)
    INSERT INTO TESTLMN(HeadId,DetailInfo) VALUES (@i,NEWID())
    SET @i=@i+1
END
GO

 

3. 索引视图创建

那么如何创建索引视图呢?语法上跟创建普通视图差别不大,但是不允许出现select *,表名上要加上Scheme,如下会做简单说明。

(1)创建语法

CREATE VIEW V_IndexViewTest WITH SCHEMABINDING
AS
    SELECT H.HeadId,H.CreateDate,H.DataStatus,D.DetailId,D.DetailInfo
    FROM dbo.TESTZYY H INNER JOIN 
                dbo.TESTLMN D ON H.HeadId = D.HeadId
    WHERE H.DataStatus = 0
GO;

(2)为索引视图创建索引

索引视图要求创建的第一个列为唯一聚集索引,所以如下,创建一个唯一的聚集索引。

create unique clustered index idx_headid
on V_IndexViewTest(detailid);

对于其他索引,可以跟在表上创建索引一样

create index idx_createdate on V_IndexViewTest(Createdate);

 4. 查询重写

上面说了,查询重写就是将基于原始表的查询语句,直接在索引视图上查询实现,那么就来看一下查询重写是什么样子的?

下面来观察这么一个查询,SQL很明显地是基于原始表做的查询,跟普通查询并无二致,但是观察执行计划就会发现:这个执行计划走了一个索引查找,首先很清楚,TESTZYY上的CreateDate是没有索引的,这里走的索引就是V_IndexViewTest上的CreatDate列上的索引,也就是在索引视图上创建的第二个索引。

select H.headid,H.createdate,D.detailid,D.detailinfo
from dbo.TESTZYY H inner join
     dbo.TESTLMN D on H.headid = D.headid
where H.datastatus = 0
and H.createdate > '2022-10-01 00:00:00.000'
and H.createdate < '2022-10-02 00:00:00.000'

 如果,查询语句这么写,如下,在查询条件中增加了一个索引视图中没有的列,此时查询就不会被重写,直接走的是基于原始表的查询,跟普通查询并无二致。
其实原理不难理解,因为视图中并不包含HeadInfo这个列,如果在查询列上加上这个字段,视图中是没有这个字段的,那只能基于原始表做查询了。

select H.headid,H.createdate,H.headinfo,D.detailid,D.detailinfo
from dbo.TESTZYY H inner join
     dbo.TESTLMN D on H.headid = D.headid
where H.datastatus = 0
and H.createdate > '2022-10-01 00:00:00.000'
and H.createdate < '2022-10-02 00:00:00.000'

5. 为什么查询会被重写

上面我们看到了,对于合适的查询,查询是会被重写的,也就是查询直接基于索引视图来实现,那么为什么会直接基于视图来实现呢?


还是处于性能上的考虑,因为索引视图在创建唯一的聚集索引之后,视图就“固化了”原始表的结果集,此时的视图与普通视图最大的区别就是,视图中直接存储了数据本身,而非一个查询,此时的视图中的数据集,相当于基于原表的一个“子集”,因为是子集,这个结果集必然小于原始表,那么同样的查询字段和查询条件,不但可以减少表与表之间的链接操作,且结果集更小,从这个视图上查询,因此同等条件下可以更快地返回结果,所以查询重写也就不难理解了。

结合上述结论,此时只要查询字段和查询条件一样,基于原始表的查询和直接查询索引视图是一样的,如下截图 :

select H.headid,H.createdate,D.detailid,D.detailinfo
from dbo.TESTZYY H inner join
     dbo.TESTLMN D on H.headid = D.headid
where H.datastatus = 0 and H.createdate > '2022-10-01 00:00:00.000' 
and H.createdate < '2022-10-02 00:00:00.000';

select headid,createdate,detailid,detailinfo
from dbo.V_IndexViewTest
where datastatus = 0 and createdate > '2022-10-01 00:00:00.000'
and createdate < '2022-10-02 00:00:00.000';

 

 6. 索引视图什么时候更新

上面说了查询重写,如果条件允许,基于原始表的查询会直接从索引视图上来实现。可能有人会不放心,毕竟数据都是基于物理表做增删改的,而索引视图中的数据又是物理存在的,那就就会有一个担心,基于视图的查询会不会不准确?毕竟是我好好的一个查询,你默认给我定位到索引视图上,查询结果会跟原始表查询一致吗?

那么就要求证一下,索引视图中的数据是如何更新的。我们做这么一个测试,在基表,也就是TESTLMN中查询一条数据,看看到底在执行计划中发生了什么 可以明显地看到,不仅仅是往TESTLMN中写入了一条数据,同时,基于索引视图的查询也往索引视图中写入了一条数据,因此可以放心地使用索引视图而不必担心索引视图中的数据和基表的数据不一致的问题。

但是要注意的就是,此时的写,是写入基表的同事,也写入了索引视图,对写入的影响是肯定有一些的,如果对写入效率要求非常高,就要谨慎一点了。其实索引视图也是一种冗余写来实现查询效率的提高的。

insert into dbo.TESTLMN(HeadId,DetailInfo) values (666,newid());

7. 改变基于视图的查询

上面说了,某些基于视图的查询,是直接定位到视图,从视图中查询结果返回的,如下图

 

 

 

但是如果真的不想从视图中查询,我就是想对比一下原始表和基于视图查询的(效率上的)区别,该怎么办?这个也好办,可以通过查询提示,将查询来基于原始表实现,也就是展开这个索引视图了OPTION (EXPAND VIEWS)这个查询提示就是将视图展开,从原始表进行查询,默认情况下是不展开的。如截图,可以强制展开索引视图,从原始表查询 :

select headid,createdate,detailid,detailinfo
from dbo.V_IndexViewTest
where datastatus = 0 and createdate > '2022-10-01 00:00:00.000'
and createdate < '2022-10-02 00:00:00.000' option(expand views);

那么效率对比呢?如下截图,粗看起来,这个效率差别还是挺大的,可见,SQL Server默认选择下,载效率上还是有一定的考虑的

这里从索引视图查询,一是减少了表之间的join,而是索引视图的结果集更小,从中筛选符合条件的数据效率就会更好一些。所以,默认情况下是会从视图查询来对SQL进行查询重写的。索引视图的查询提示:with(no expand) 强制不展开,OPTION (EXPAND VIEWS)强制展开。

总结:

  本文粗浅地分析了SQL Server 中的索引视图以及索引视图带来的查询重写功能,通过索引视图固化基表的结果集,
  可以在一定程度上提高查询效率,尤其是在超级大的多表join的时候,直接将原始结果存为一个索引视图,
  通过对索引视图查询来减少表之间的join和IO来提高效率,不失为一种优化选择。
  需要注意的是,SQL Server的索引视图限制非常多,具体可以参考链接丛书或者MSND,并不是所有的情况都可以使用索引视图来实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/23647.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一篇文章详解Linux的用户和权限

教程推荐&#xff1a;Linux零基础快速入门到精通 认知root用户 root用户&#xff08;超级管理员&#xff09; 无论是Windows、MacOS、Linux均采用多用户的管理模式进行权限管理。 •在Linux系统中&#xff0c;拥有最大权限的账户名为&#xff1a;root&#xff08;超级管理员&a…

第十七届全国人机语音通讯学术会议(NCMMSC 2022) | 早鸟票开放注册了

全国人机语音通讯学术会议是国内语音领域广大专家、学者和科研工作者交流最新研究成果&#xff0c;促进该领域研究和开发工作不断进步的重要舞台。该系列会议自1990年开创以来已成功召开了十六届。2022年第十七届全国人机语音通讯学术会议&#xff08;National Conference on M…

移动WEB开发之流式布局--移动端常见布局--流式布局

移动端技术选型 移动端布局和以前我们学习的PC端有所区别&#xff1a; 1. 单独制作移动端页面&#xff08;主流&#xff09; 流式布局&#xff08;百分比布局&#xff09; flex 弹性布局&#xff08;强烈推荐&#xff09; lessrem媒体查询布局 混合布局 2. 响应式页面兼…

ConcurrentHashMap的实现原理是分段锁?你Out了

前言 Java后端开发面试的时候&#xff0c;一场好的面试&#xff0c;是无论如何也绕不开并发编程的。并发编程里面往往有个很重要的类可能会被拿出来探讨&#xff1a;ConcurrentHashMap。 ConcurrentHashMap是HashMap的线程安全版。大家都知道HashMap的高性能&#xff0c;但是H…

动静态库的制作

目录 一.动静态库的原理 二.静态库 2.1制作静态库 2.2使用静态库 三.动态库 3.1制作动态库 3.2动态库的使用 一.动静态库的原理 首先要知道可执行程序的生成过程&#xff1a;1&#xff0c;预处理 2&#xff0c;编译 3&#xff0c;汇编 4 &#xff0c;链接 1.预处理 头…

03 LaTex之标题页摘要

1.标题页 \title{{ABC}\footnote{explain}}%生成标题和标题的脚注\author{\small $^a$lay \qquad $^b$winter \footnote{super star}\\%换行符 %作者信息 \small $^a$ lays brief\\ \small lays address, 710021\\%换行 \small $^b$ winters introduction \\ \small winters …

0101 蓝桥杯真题04

/* * 马虎的算式 * 小明是个急性子&#xff0c;上小学的时候经常把老师写在黑板上的题目抄错了。 * 有一次&#xff0c;老师出的题目是&#xff1a;36 x 495 ? * 他却给抄成了&#xff1a;396 x 45 ? * 但结果却很戏剧性&#xff0c;他的答案竟然是对的&#xff01;&a…

同花顺_代码解析_技术指标_Z_3

本文通过对同花顺中现成代码进行解析&#xff0c;用以了解同花顺相关策略设计的思想 目录 ZNZ_DPCYC1 ZNZ_DPCYR ZNZ_HLD ZNZ_HUO ZNZ_MYL1 ZNZ_MYP1 ZNZ_PAS ZNZ_PAS1 ZNZ_RPY1 ZNZ_RPY2 ZNZ_SDR ZNZ_TAO ZNZ_YHBOL1 ZNZ_YHCBB ZX ZNZ_DPCYC1 大盘成本均线 行…

python 给图片添加噪声

import numpy as np import cv2 import matplotlib.pyplot as plt import skimage from skimage import io import randomdef addGaussNoise(origin,var0.0005):#添加高斯噪声函数var random.uniform(0.0001, 0.04)noisy skimage.util.random_noise(origin, modegaussian, va…

idea iu 2021 Mac版本的使用,如何创建java web项目,包括tomcat和web包

Java web系列文章目录 第一章 前端学习入门之idea iu 2021版本的使用 目录Java web系列文章目录前言一、Java web是什么&#xff1f;二、配置步骤1.下载Tomcat服务器2.idea iu 2021版本界面总结前言 随着前端的学习路径&#xff0c;java web项目不可避免要学习使用&#xff0…

YUV与RGB 以及之间的转换

目录 一、RGB 二、YUV 三、YUV类型和存储方式 1、类型 2、存储方式 四、分析YUV 4:2:0 1、YU12(I420&#xff0c;YUV420P) 2、YV12 3、NV12(YUV420SP) 4、NV21(YUV420SP) 5、占用空间大小比较 五、RGB与YUV之间的转换 1、转换标准 2、Color Range 3、计算公式 在…

【ArcGIS】属性表导出及乱码问题

这玩意其实说难不难&#xff0c;但是乱码有时候还是烦人 直接复制到EXCEL 部分表细节被我删掉了 直接点击全选&#xff0c;然后复制&#xff0c;再到EXCEL里粘贴。我有时候就是这么干的。而且量大概是二十万行左右。 Table to Table 如果你的属性文件大于65533行&#xff…

十一、组合API(1)

本章概要 为什么要引入组合APIsetup() 函数 组合&#xff08;Composition&#xff09;API 是在 Vue 3.0 中引入的&#xff0c;它是一组附加的、基于函数的 API &#xff0c;允许灵活地组合组件逻辑。 组合 API 并没有引入新的概念&#xff0c;更多地是将 Vue 的核心功能&…

项目相互依赖调用解决方法两种方法

Bmodel依赖于Amodel&#xff0c;但是Amodel又需要BModel的信息。原来是在Amodel创建一块内存&#xff0c;在Bmodel中将内存地址赋给这块内存&#xff0c;然后在Amodel去做其他操作。 方法一&#xff1a;采用静态变量static链接&#xff1a;C开发中一个解决方案里&#xff0c;两…

LeetCode 0808. 分汤:好题【感叹号】

【LetMeFly】808.分汤&#xff1a;好题&#xff01; 力扣题目链接&#xff1a;https://leetcode.cn/problems/soup-servings/ 有 A 和 B 两种类型 的汤。一开始每种类型的汤有 n 毫升。有四种分配操作&#xff1a; 提供 100ml 的 汤A 和 0ml 的 汤B 。提供 75ml 的 汤A 和 2…

Google Earth Engine(GEE)—— 各矿区时序NDVI变化图(包含具体的运行函数)

函数: ee.Filter.eq(name, value) Filter to metadata equal to the given value. Returns the constructed filter. Arguments: name (String): The property name to filter on. value (Object): The value to compare against. Returns: Filter ui.Chart.image.s…

7、Jedis测试

文章目录7、Jedis测试7.1. Jedis所需要的jar包7.2. 连接Redis注意事项7.3. Jedis常用操作7.3.1. 创建动态的工程7.3.2. 创建测试程序7.4. 测试相关数据类型7.4.1. Jedis-API&#xff1a;Key7.4.2. Jedis-API&#xff1a;String7.4.3. Jedis-API&#xff1a;List7.4.4. Jedis-AP…

葡萄糖-聚乙二醇-6-羧甲基荧光素 Glucose-PEG-6-FAM

葡萄糖-聚乙二醇-6-羧甲基荧光素 Glucose-PEG-6-FAM 中文名称&#xff1a;葡萄糖-6-羧甲基荧光素 英文名称&#xff1a;Glucose-6-FAM 别称&#xff1a;6-羧甲基荧光素标记葡萄糖&#xff0c;6-羧甲基荧光素-葡萄糖 PEG接枝修饰葡萄糖 Glucose-PEG-6-FAM 葡萄糖-聚乙二醇…

需求收集方法工具,以及进行需求分析的6大要素

通过本文你将了解&#xff1a;1、需求管理流程包括哪四个步骤&#xff1b;2、如何进行需求收集&#xff1b;3、如何进行需求分析&#xff1f;4、如何进行需求分发&#xff1b;5、如何进行需求验证&#xff1b;6、有哪些辅助软件需求管理的工具系统&#xff1f;一、需求管理包括…

MyBatis核心配置文件

1.environments 注 : environments下面可以配置多个环境 , 需要使用哪个环境default里面的参数就对应哪个Id. 2.properties 配置连接 方法一 :(直接配置参数) 方法二 :(使用properties配置文件) (1)创建一个 properties 文件 , 在里面配置连接 (2)在核心配置文件中配置使用p…