为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:DM 8.1
【操作系统】:Ubuntu 22.04
【CPU】:
【问题描述】*:WHERE子句包含多列组合IN谓词(行值构造器)时,优化器未能利用主键索引,执行计划严重偏离预期,导致查询响应时间从毫秒级劣化至秒级。
两条查询语义完全等价,但性能相差约 1635 倍。
CREATE TABLE t0 (c0 INT PRIMARY KEY);
CREATE TABLE t1 (c0 INT PRIMARY KEY);
INSERT INTO t0 SELECT ROWNUM FROM DUAL CONNECT BY ROWNUM <= 1000000;
INSERT INTO t1 SELECT ROWNUM FROM DUAL CONNECT BY ROWNUM <= 1000;
SELECT * FROM t0, t1 WHERE (t0.c0, t1.c0) IN ((0,0),(1,1));
-- 实际执行耗时:约 7.4 秒
SELECT * FROM t0, t1 WHERE (t0.c0 = 0 AND t1.c0 = 0) OR (t0.c0 = 1 AND t1.c0 = 1);
-- 实际执行耗时:4.527 毫秒
查询计划分析:
1 #NSET2: [19801482, 50000000, 8]
2 #PRJT2: [19801482, 50000000, 8]; exp_num(2), is_atom(FALSE)
3 #HASH RIGHT SEMI JOIN2: [19801482, 50000000, 8]; n_keys(2)
KEY(DMTEMPVIEW_889193482.colname=T0.C0 AND DMTEMPVIEW_889193482.colname=T1.C0)
KEY_NULL_EQU(0, 0)
4 #CONST VALUE LIST: [1, 2, 8]; row_num(2), col_num(2)
5 #NEST LOOP INNER JOIN2: [19801482, 50000000, 8]
6 #SSCN: [1, 1000, 4]; INDEX33555474(T1); btr_scan(1); is_global(0)
7 #SSCN: [105, 1000000, 4]; INDEX33555472(T0); btr_scan(1); is_global(0)
预期执行计划:优化器应识别多列 IN 谓词与 OR 展开的等价性,将条件直接下推至基表扫描阶段,分别通过主键索引定位 (0,0) 和 (1,1) 两行数据,时间复杂度应为常数级。

加hint能解决:
SELECT /*+ENABLE_IN_VALUE_LIST_OPT(65)*/* FROM t0, t1 WHERE (t0.c0, t1.c0) IN ((0,0),(1,1)); 1 #NSET2: [1, 2, 16] 2 #PRJT2: [1, 2, 16]; exp_num(2), is_atom(FALSE) 3 #HASH2 INNER JOIN: [1, 2, 16]; RKEY_UNIQUE KEY_NUM(1); KEY(DMTEMPVIEW_889213328.colname=T1.C0) KEY_NULL_EQU(0) 4 #NEST LOOP INDEX JOIN2: [1, 2, 16] 5 #ACTRL: [1, 2, 16] 6 #NEST LOOP INDEX JOIN2: [1, 2, 12] 7 #CONST VALUE LIST: [1, 2, 8]; row_num(2), col_num(2) 8 #SSEK2: [1, 1, 4]; scan_type(ASC), INDEX33555587(T0), scan_range[DMTEMPVIEW_889213328.colname,DMTEMPVIEW_889213328.colname], is_global(0) 9 #SSEK2: [1, 1, 4]; scan_type(ASC), INDEX33555589(T1), scan_range[DMTEMPVIEW_889213328.colname,DMTEMPVIEW_889213328.colname], is_global(0) 10 #SSCN: [1, 1000, 4]; INDEX33555589(T1); btr_scan(1); is_global(0)