YashanDB|使用 select * 创建物化视图无法触发查询重写?问题出在这儿!

在使用 YashanDB 的物化视图功能进行查询优化时,有用户遇到如下困惑:

"我明明启用了查询重写,为什么语句还是没有命中物化视图?"

经过实际验证,问题出在一个细节------使用了 select * 创建物化视图。本文将带你分析问题原因,并给出规避建议。

一、问题现象

使用如下语句创建基础表与物化视图:

sql 复制代码
alter system set query_rewrite_enabled = force scope=both;
create table test(tid number, tname varchar2(30));
begin
for i in 1..100000 loop
insert into test values(i, i || 'abcd');
end loop;
end;
/
commit;
create materialized view mv_1 as
select * from test where tid = 66;
alter materialized view mv_1 enable query rewrite;

之后执行以下查询:

csharp 复制代码
select * from test where tid = 66;
select tid, tname from test where tid = 66;

均未触发查询重写!

但当我们使用带双引号的大写列名查询时:

csharp 复制代码
select "TID", "TNAME" from test where tid = 66;

查询重写成功命中物化视图。

二、问题风险与影响

重写未命中 → 查询无法利用预聚合视图 → 性能大打折扣;

用户难以定位问题原因,误以为功能不可用;

查询优化效果严重依赖于使用者写 SQL 的"方式"。

三、问题根因剖析

目前 YashanDB 的物化视图重写机制,是通过文本列名匹配来判断是否可以重写的,而不是基于语义或查询逻辑。

具体机制:

使用 select * 创建物化视图时,系统会将其展开为:

csharp 复制代码
select "TID", "TNAME" ...

但当查询语句写为:

csharp 复制代码
select tid, tname from test ...

或者

csharp 复制代码
select * from test ...

则匹配机制无法识别为等价表达,重写失败。

哪怕是写成:

csharp 复制代码
select TID, TNAME ...

由于未加双引号,也不会与 "TID", "TNAME" 匹配成功。

四、影响版本

目前所有 YashanDB 版本均存在该问题。

五、规避建议与解决方法

建议一:创建物化视图时避免使用select *

改为显式列名 + 大写 + 加双引号,例如:

sql 复制代码
create materialized view mv_1 as
select "TID", "TNAME" from test where tid = 66;

建议二:查询时也保持格式一致

查询时尽量写为:

csharp 复制代码
select "TID", "TNAME" from test where tid = 66;

这样最容易命中已存在的物化视图。

建议三:统一命名规范

在数据库设计与开发中统一约定使用大写列名,并强制加双引号,是当前阶段下提升查询重写命中率的有效手段。

六、改进建议

当前 YashanDB 的物化视图重写功能仍处于初级阶段,建议未来版本从"语义等价"角度进行匹配,而不是依赖列名文本比较。

比如参考 Oracle 的方式,可通过:

查询逻辑结构比对;

抽象语法树(AST)等价分析;

聚合字段、表达式规范化识别;

提升查询重写的智能化水平。

七、总结

相关推荐
天草二十六_简村人12 小时前
阿里云SLS采集jvm日志(上)
java·运维·数据库·后端·阿里云·容器·云计算
Java面试题总结12 小时前
MongoDB(70)如何使用副本集进行备份?
数据库·mongodb
荒川之神12 小时前
Oracle LEVEL 函数练习(HR 模式 employees 表)
数据库·oracle
TDengine (老段)13 小时前
TDengine IDMP 工业数据建模 —— 元素与数据查询
大数据·数据库·人工智能·物联网·时序数据库·tdengine·涛思数据
蜡台13 小时前
Mysql 安装与配置
数据库·mysql
lajidecrd13 小时前
Ubuntu24安装PostgreSQL和PgVector
数据库·postgresql
羊小猪~~13 小时前
Redis学习笔记(数据类型、持久化、事件、管道、发布订阅等)
开发语言·数据库·c++·redis·后端·学习·缓存
福娃筱欢13 小时前
Oracle迁移KES提示ERROR: type “geometry“ does not exist
数据库·oracle
mldlds13 小时前
使用 Qt 插件和 SQLCipher 实现 SQLite 数据库加密与解密
数据库·qt·sqlite
大空大地202613 小时前
Entity Framework
数据库