为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:
DM Database Server 64 V8
DB Version: 0x7000d
03134284552-20260414-322369-20221
Msg Version: 1
Gsu level(5) cnt: 102
DM 管理工具
【操作系统】:
Windows 11 64 位
【CPU】:
Intel x86_64
【问题描述】*:
在 DM8 中,将 REAL 类型列通过 ROUND(C6, 2) 计算后作为视图或 CTE 的输出列,并使用该输出列进行自连接时,查询返回2行。
将完全相同的查询结果通过 CTAS 物化到 ON COMMIT PRESERVE ROWS 全局临时表后,再执行相同的自连接查询,返回4行。
结果对比如下:
视图自连接: 2行,结果为 1、0
CTE自连接: 2行,结果为 1、0
CTAS临时表自连接: 4行,结果为 1、1、0、0
怀疑视图或 CTE 在展开、上拉或连接谓词改写过程中,没有按照 ROUND(C6,2) 派生列的结果进行比较,而是使用了不同的内部表达式或精度进行连接。
该现象会改变 LEFT JOIN 的匹配基数和最终查询结果,请协助确认是否为查询优化或表达式处理问题。
复现脚本:
CREATE SCHEMA database0;
SET SCHEMA database0;
drop table if EXISTS T_DM_2377;
drop view if EXISTS V_DM_2377;
drop table if EXISTS TEMP_DM_2377;
drop table if EXISTS TEMPOCPR_DM_2377;
CREATE TABLE T_DM_2377 (C0 BIGINT, C1 BIGINT, C2 NUMERIC(1,1), C3 INTEGER, C4 CLOB, C5 FLOAT, C6 REAL, C7 TINYINT);
INSERT INTO T_DM_2377 (C0, C1, C2, C3, C4, C5, C6, C7) VALUES ('1', NULL, 0, -626610, '中文', NULL, -1e-12, -57);
INSERT INTO T_DM_2377 (C0, C1, C2, C3, C4, C5, C6, C7) VALUES ('0', '2', -0, 2147483647, 'pOqJVJHKMKNindW12juYwK0dIwo8I4_bVyQpNU8wnlSsPluoZOfEgXQgf6qsZMpP cikjqXU1n51Ccp8u5a8.o2wJj5jI1d2oXqkLicPUTU20kQ6uqfO413sU2PHPhWIrq0W8odTSnSTPCG1Jwep5JVy5qWsagk6tu-IZbtnIW02XfdjI.4EdufrN-BX2t bMa7x3sqvEQEwWMAx3b_IkKqtWWrv4Qyg2LjiNbdkQr1ohCn4mYYytpWTC4BbYrrp-4Uub8uugjdYU4b7ExM0CXBhNmwnXQFxUva6H0BIGS9oy6SMzmtu6lW.VbTEmq14pCKqRV.Lg7dnpql9MZx_KLbsXTmq2owi5iO31EZAuXjNgWFI3EPQwr0ZZs8qYN4u-oxlrGMx', 844041.613647193, -0.0, 1);
CREATE VIEW V_DM_2377 (VC_0, VC_1, VC_2) AS SELECT ROUND(C6, 2) AS VC_0, FLOOR(C5) AS VC_1, BITAND(C0, 1) AS VC_2 FROM T_DM_2377;
SELECT A.VC_2 FROM V_DM_2377 A LEFT JOIN V_DM_2377 B ON A.VC_0=B.VC_0;
-- row =2
-- 1
-- 0
WITH CTE AS (SELECT ROUND(C6, 2) AS VC_0, FLOOR(C5) AS VC_1, BITAND(C0, 1) AS VC_2 FROM T_DM_2377) SELECT A.VC_2 FROM CTE A LEFT JOIN CTE B ON A.VC_0=B.VC_0;
-- row =2
-- 1
-- 0
CREATE GLOBAL TEMPORARY TABLE TEMP_DM_2377 ON COMMIT PRESERVE ROWS AS SELECT ROUND(C6, 2) AS VC_0, FLOOR(C5) AS VC_1, BITAND(C0, 1) AS VC_2 FROM T_DM_2377;
SELECT A.VC_2 FROM TEMP_DM_2377 A LEFT JOIN TEMP_DM_2377 B ON A.VC_0=B.VC_0;
-- row =4
-- 1
-- 1
-- 0
-- 0
视图、CTE和临时表的源查询完全相同,外层连接条件也完全相同,但物化前后连接结果不一致。
初步判断
由于 CTAS 物化后两个 VC_0 值可以互相匹配,而视图和 CTE 中不能完全匹配,怀疑与以下过程有关:
视图展开或上拉;
CTE展开或上拉;
ROUND(REAL,2) 表达式的等值连接改写;
派生列连接谓词下推;
浮点表达式在物化前后的类型或精度处理不一致。
本问题不是单纯的浮点结果末位差异,而是等值连接的匹配关系和最终返回行数发生变化。

PHC_MODE_ENFORCE(11) 或者enable_hash_join(0) 禁用下hash可以绕过
SELECT /*+ PHC_MODE_ENFORCE(11) */A.VC_2 FROM V_DM_2377 A LEFT JOIN V_DM_2377 B ON A.VC_0=B.VC_0;