indexed views(索引视图)实际索引的内容到底是什么?
索引视图(Indexed Views)底层运行原理解析
你提到的两种猜测里,第一种完全不成立,第二种是索引视图的真实实现逻辑,具体原理如下:
1. 索引视图的存储本质
普通无索引的视图确实是虚拟表,仅存储查询定义,执行时才会展开为对应的SQL语句跑在基表上。但一旦给视图创建了索引,它就不再是虚拟结构:
- 为视图创建的第一个索引必须是唯一聚集索引,创建过程会直接执行视图对应的查询,把结果集物理化存储到磁盘上,相当于生成了一份符合视图过滤条件的独立数据副本,和普通表的存储结构没有区别。
- 以你举的例子为例,视图定义为
SELECT * FROM bookings WHERE IsDeleted=0,聚集索引创建完成后,所有IsDeleted=0的bookings表行都会被持久化存储,索引的叶子节点就是完整的行数据,后续你再基于AppointmentDate创建非聚集索引,也是直接基于这份物化副本的聚集索引键来构建,不会直接引用基表的主键。
2. 基表变更的同步机制
你担心的同步开销是真实存在的:
- 当基表
bookings发生增删改操作时,数据库引擎会自动判断变更是否会影响索引视图的结果集,如果会则同步更新索引视图的物化存储:- 把
IsDeleted=1的行改为IsDeleted=0:引擎会自动将这行插入到索引视图的物化副本中 - 把
IsDeleted=0的行改为IsDeleted=1:引擎会自动从索引视图中删除这行 - 修改行的
AppointmentDate值:引擎会同步更新索引视图中对应非聚集索引的排序位置
- 把
- 这个同步是事务级别的,基表的变更事务必须同时完成索引视图的更新才算提交成功,因此会提升基表的写入延迟。
3. 适用场景与开销平衡
索引视图的性能收益是否能覆盖写入开销,完全取决于业务场景:
- 适合使用的场景:
- 基表读操作远多于写操作,比如历史数据、报表统计类的表,很少发生变更,频繁执行固定条件的查询、聚合
- 视图定义包含多表关联、复杂聚合逻辑,每次查询时展开计算的成本很高,提前物化的收益远大于写入同步的开销
- 不适合使用的场景:
基表写入非常频繁,比如实时交易流水类的表,每秒有大量增删改操作,此时同步索引视图的开销会远大于查询带来的收益,这种场景直接给基表加对应索引更合适。
内容的提问来源于stack exchange,提问作者andrew pate
相关产品推荐
相关产品推荐

